2012-10-05 9 views
6

Ich versuche, UDP mit Datagramm in JAVA zu senden und meine Maschine haben mehrere NIC mit verschiedenen IPs.JAVA set/wählen Sie eine bestimmte NIC von mehreren (UDP)

Wie kann ich einstellen, von welcher NIC ich mein Paket gesendet werden soll ?? (Vorausgesetzt, ich habe mehr als eine an der Maschine ??)

EDIT I ​​

Ich bin nicht Sockel verwenden, ich bin mit Datagram und versuchte, wie dies zu tun Bindung:

/*binding */ 
     DatagramSocket ds = new DatagramSocket(1111); 
     NetworkInterface nif = NetworkInterface.getByIndex(nicIndex); 
     Enumeration<InetAddress> nifAddresses = nif.getInetAddresses(); 
     ds.bind(new InetSocketAddress(nifAddresses.nextElement(), 0)); 

Aber wenn Ich mache das, ich kann mich nicht mehr verbinden (oder bekomme das Paket nicht ..). Das Problem ist, dass ich 2 NIC haben, aber man ist für die interne Netzwerk und das andere ist für Internet .. Ich brauche alle meine Server-Daten nur auf die internen Audio zu gehen ..

EDIT II

Zur Klärung. Diese App ist ein Server - und der Server hat 2 NICS. ein LAN und eins für WAN.

Eine alternative Möglichkeit für mich, würde eine ROUTING irgendwie zu spezifizieren - was bedeutet, jedes Paket genau zu sagen, welche NIC zu verwenden, um ..

Wie ein solches Routing in JAVA tun ??

Antwort

2

Die Socket Klasse hat eine constructor, die ein localAddr Argument dauert. Das könnte für Sie gelten?

Bearbeiten: 1) Führen Sie nicht in Java Routing, überlasse das dem Betriebssystem.

2) Ich hoffe, Sie haben All About Datagrams besucht?

3) Der Server 0.0.0.0 binden kann (dh eine beliebige IP an der Maschine) das ist, was passiert, wenn Sie nur einen Port in der DatagramSocket Konstruktor angeben, oder es kann auf eine bestimmte Schnittstelle binden, wenn Sie den DatagramSocket(int port, InetAddress laddr) Konstruktor wählen - diese was du tun solltest!

4) Der Client sendet dann alles, was gesendet werden muss, und der Server kann antworten, indem er den in 3) erstellten Socket und das Ziel packet.getAddress()/packet.getPort() verwendet.

Cheers,

+0

Ich benutze DatagramSocket Klasse, lesen Sie bearbeiten I – user1722362

+0

Verdammt - Entschuldigung für die fehlende. Ich bin ein bisschen neugierig, warum Sie das im Code lösen wollen, anstatt sich auf IP-Routing zu verlassen? Wenn Sie Ihr UDP-Paket an eine bestimmte IP-Adresse senden und dieser Server sich im internen Netzwerk befindet, sollte der IP-Stapel das Paket automatisch über die entsprechende NIC-Schnittstelle automatisch weiterleiten. Oder vermisse ich noch mehr? –

+0

Sind Sie auch sicher, dass das erste Element in der Aufzählung immer Ihre bevorzugte NIC ist - was, wenn es die Loopback-Schnittstelle oder eine exotische 6to4-Tunnelschnittstelle ist? –

1

Von Tutorial docs Here, „, um die Daten zu senden, stellt das System fest, welche Schnittstelle. Allerdings verwendet wird, wenn Sie eine Präferenz haben oder auf andere Weise angeben müssen, welche NIC können Sie verwenden abfragen das System für die entsprechenden Schnittstellen und finden Sie eine Adresse auf der Schnittstelle, die Sie verwenden möchten. "

Auf die NetworkInterFaces kann programmgesteuert zugegriffen werden als,
Enumeration en = NetworkInterface.getNetworkInterfaces();

Iterating jede Sie können InetAddress damit verbunden und verwenden Sie die InetAddress, um Sie Datagramm Socket zu konstruieren.
Es gibt gute Informationen in dieser Frage - How to enumerate IP addresses of all enabled NIC cards from Java?

Hoffnung, dass,

0

Hier hilft meist kompletter Code, den ich verwenden. In meinem Fall kenne ich das von meiner Verbindung verwendete IP-Präfix. Möglicherweise müssen Sie nach dem Namen der Schnittstelle suchen und ihn mit einem Wert vergleichen, den Sie in einer Konfigurationsdatei speichern.

Beachten Sie die Verwendung von MulticastSocket anstelle von DatagramSocket, sodass die Methode setNetworkInterface verfügbar ist, um die gewünschte Schnittstelle zu binden. Da MulticastSocket eine untergeordnete Klasse von DatagramSocket ist, verursacht der Switch im Allgemeinen keine Probleme.

@Override 
public void connect() throws InterruptedException 
{ 

    NetworkInterface iFace; 

    iFace = findNetworkInterface(); 

    connectControlBoard(iFace); 

    connectUTBoards(iFace); 

}//end of Capulin1::connect 
//----------------------------------------------------------------------------- 

//----------------------------------------------------------------------------- 
// Capulin1:findNetworkInterface 
// 
// Finds the network interface for communication with the remotes. Returns 
// null if no suitable interface found. 
// 
// The first interface which is connected and has an IP address beginning with 
// 169.254.*.* is returned. 
// 
// NOTE: If more than one interface is connected and has a 169.254.*.* 
// IP address, the first one in the list will be returned. Will need to add 
// code to further differentiate the interfaces if such a set up is to be 
// used. Internet connections will typically not have such an IP address, so 
// a second interface connected to the Internet will not cause a problem with 
// the existing code. 
// 
// If a network interface is not specified for the connection, Java will 
// choose the first one it finds. The TCP/IP protocol seems to work even if 
// the wrong interface is chosen. However, the UDP broadcasts for wake up calls 
// will not work unless the socket is bound to the appropriate interface. 
// 
// If multiple interface adapters are present, enabled, and running (such as 
// an Internet connection), it can cause the UDP broadcasts to fail. 
// 

public NetworkInterface findNetworkInterface() 
{ 

    logger.logMessage(""); 

    NetworkInterface iFace = null; 

    try{ 
     logger.logMessage("Full list of Network Interfaces:" + "\n"); 
     for (Enumeration<NetworkInterface> en = 
       NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { 

      NetworkInterface intf = en.nextElement(); 
      logger.logMessage(" " + intf.getName() + " " + 
               intf.getDisplayName() + "\n"); 

      for (Enumeration<InetAddress> enumIpAddr = 
        intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { 

       String ipAddr = enumIpAddr.nextElement().toString(); 

       logger.logMessage("  " + ipAddr + "\n"); 

       if(ipAddr.startsWith("/169.254")){ 
        iFace = intf; 
        logger.logMessage("==>> Binding to this adapter...\n"); 
       } 
      } 
     } 
    } 
    catch (SocketException e) { 
     logger.logMessage(" (error retrieving network interface list)" + "\n"); 
    } 

    return(iFace); 

}//end of Capulin1::findNetworkInterface 
//----------------------------------------------------------------------------- 

//----------------------------------------------------------------------------- 
// Capulin1::connectControlBoards 
// 

public void connectControlBoard(NetworkInterface pNetworkInterface) 
                throws InterruptedException 
{ 

    logger.logMessage("Broadcasting greeting to all Control boards...\n"); 

    MulticastSocket socket; 

    try{ 
     socket = new MulticastSocket(4445); 
     if (pNetworkInterface != null) { 
      try{ 
       socket.setNetworkInterface(pNetworkInterface); 
      }catch (IOException e) {}//let system bind to default interface 
     } 

    } 
    catch (IOException e) { 
     logSevere(e.getMessage() + " - Error: 204"); 
     logger.logMessage("Couldn't create Control broadcast socket.\n"); 
     return; 
    } 

...use the socket here... 
2

Ich hatte gerade das gleiche Problem von dir. Es war nicht sofort um das Problem zu lösen, aber schließlich habe ich einige Code, der Ihnen nützlich sein können:

//set Network Interface 
     NetworkInterface nif = NetworkInterface.getByName("tun0"); 
     if(nif==null){ 
      System.err.println("Error getting the Network Interface"); 
      return; 
     } 
     System.out.println("Preparing to using the interface: "+nif.getName()); 
     Enumeration<InetAddress> nifAddresses = nif.getInetAddresses(); 
     InetSocketAddress inetAddr= new InetSocketAddress(nifAddresses.nextElement(),0); 

     //socket.bind(new InetSocketAddress(nifAddresses.nextElement(), 0)); 
     DatagramSocket socket = new DatagramSocket(inetAddr); 
     System.out.println("Interface setted"); 

ich eine Menge Ausgabe verwendet um sicher zu sein, dass der Code richtig funktioniert und es so aussehen, es zu tun , Ich arbeite immer noch daran, aber ich nehme an, das kann genug für Ihr Problem sein

Verwandte Themen