2012-10-05 8 views
6

Sto cercando di inviare UDP con datagramma in JAVA e la mia macchina ha diversi NIC con diversi IP.JAVA imposta/seleziona NIC specifica da più (UDP)

Come posso impostare quale NIC voglio che il mio pacchetto venga inviato da ?? (Supponendo che ho più di uno sulla macchina ??)

EDIT ho

non sto usando Socket, sto usando DatagramSocket e cercato di fare vincolante in questo modo:

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

Ma quando Lo faccio, non riesco più a connettermi (o non riesco a ottenere il pacchetto ..). Il problema è che ho 2 NIC, ma uno è per la rete interna e l'altra è per Internet .. ho bisogno di tutti i miei dati del server di andare solo su quello interno ..

EDIT II

Per chiarimenti. Questa App è un server e il SERVER ha 2 NICS. una LAN e una per WAN.

Un modo alternativo per me sarebbe di specificare un ROUTING in qualche modo - il che significa dire a ogni pacchetto esattamente quale NIC da usare ..

come fare un esempio di routing in JAVA ??

risposta

2

La classe Socket ha un constructor che accetta un argomento localAddr. Potrebbe essere applicabile a te?

Modifica: 1) Non eseguire il routing in Java, lasciare questo al sistema operativo.

2) Confido che tu abbia visitato All About Datagrams?

3) Il server può legarsi a 0.0.0.0 (vale a dire qualsiasi IP sulla macchina), che è ciò che accade se si specifica solo una porta nel costruttore DatagramSocket o può legarsi a una specifica interfaccia, se si sceglie il costruttore DatagramSocket(int port, InetAddress laddr) - questo è quello che dovresti fare!

4) Il client invia quindi tutto ciò che è necessario inviare e il server può rispondere, utilizzando il socket creato in 3) e la destinazione packet.getAddress()/packet.getPort().

Cheers,

+0

sto usando la classe DatagramSocket, leggi modifica I – user1722362

+0

Verdammt - scuse per averlo mancato. Sono un po 'curioso di sapere perché vuoi risolvere questo in codice piuttosto che fare affidamento sul routing IP? Se si invia il pacchetto UDP a un determinato IP e tale server si trova sulla rete interna, lo stack IP deve instradare correttamente quel pacchetto tramite l'interfaccia NIC rilevante automaticamente. O mi manchi ancora di più? –

+0

Inoltre, sei sicuro che il primo elemento dell'enumerazione sia sempre la tua NIC preferita? E se fosse l'interfaccia di loopback o qualche interfaccia di tunnel 6to4 esotica? –

1

Da documenti Tutorial Here, "Per inviare i dati, il sistema determina quale interfaccia viene utilizzata. Tuttavia, se avete una preferenza o di necessità di specificare quale NIC da utilizzare, è possibile interrogare il sistema per le interfacce appropriate e trovare un indirizzo sull'interfaccia che si desidera utilizzare. "

È possibile accedere a NetworkInterFaces a livello di codice come,
Enumerazione en = NetworkInterface.getNetworkInterfaces();

Iterando a ciascuno è possibile ottenere InetAddress associato e utilizzare InetAddress per costruire il socket del datagramma.
C'è buone informazioni in questa domanda - How to enumerate IP addresses of all enabled NIC cards from Java?

speranza che aiuta,

0

Ecco principalmente codice completo che ho usato. Nel mio caso, conosco il prefisso dell'indirizzo IP usato dalla mia connessione. Potrebbe essere necessario cercare il nome dell'interfaccia e confrontarlo con un valore memorizzato in un file di configurazione.

Nota l'uso di MulticastSocket anziché DatagramSocket in modo che sia disponibile il metodo setNetworkInterface per collegare l'interfaccia desiderata. Poiché MulticastSocket è una classe figlia di DatagramSocket, l'opzione generalmente non causa problemi.

@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

Ho appena avuto lo stesso problema di te. Non è stato immediato per risolvere il problema ma alla fine ho scritto un po 'di codice che può essere utile per voi:

//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"); 

ho usato un sacco di uscita per essere sicuri che il codice funzioni correttamente e apparire come farlo , Ci sto ancora lavorando ma suppongo che questo possa essere sufficiente per il tuo problema

Problemi correlati