2012-10-05 14 views
6

JAVA'da UDP'yi datagram ile göndermeye çalışıyorum ve makinemin farklı IP'leri olan birkaç NIC'si var.JAVA, birden çok (UDP) belirli NIC'yi seçer/seç

Paketimin hangi NIC'den gönderileceğini nasıl ayarlayabilirim ??

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

Ama:

DÜZENLEME Ben Soket kullanmıyorum

, ben DatagramSocket kullanarak ve denenmiş am şöyle bağlama yapmak için (ben makinede ?? üzerinde birden çok var varsayarak) Bunu yapıyorum, artık bağlanamıyorum (veya paketi alamıyorum ..).

DÜZENLEME .. Sorun 2 NIC olması, ancak bir İÇ ağ için ve diğeri ben bütün sunucu verileri İÇ birinde sadece gitmek gerekir .. İnternet için olan II

Açıklama için

. Bu App bir sunucudur - ve SUNUCU 2 NICS vardır. bir LAN ve bir WAN için.

nasılsa bir yönlendirme belirtmek istiyorum benim için alternatif bir yol -

Nasıl JAVA böyle bir yönlendirme yapmak .. tam NIC Kullanılacak her paket söylemek istiyordum ??

cevap

2

Socket sınıfı, localAddr bağımsız değişkenine sahip bir constructor sınıfına sahiptir. Bu sizin için geçerli olabilir mi?

Düzenleme: 1) Java'da yönlendirme yapmayın, bunu işletim sisteminize bırakın.

2) Ziyaret ettiğiniz için güveniyorum All About Datagrams?

3) Sunucu (0.0.0.0 için yani sadece DatagramSocket yapıcı bir bağlantı noktası belirtin ya da DatagramSocket(int port, InetAddress laddr) yapıcısı seçerseniz belirli bir arayüze bağlanmasına eğer böyle olur makinede herhangi bir IP) bağlayabilir - Bu yapman gereken şey! 4) İstemci daha sonra gönderilmesi gereken her şeyi gönderir ve sunucu 3) 'de oluşturulan soketi kullanarak ve paket.getAddress()/packet.getPort() hedefini kullanarak yanıt verebilir.

Alkış, Öğretici docs Here itibaren

+0

Ben DatagramSocket sınıfı kullanıyorum, düzenleme okumak I – user1722362

+0

Verdammt - eksik için özür dilerim. Bunu IP yönlendirmesine dayanmak yerine neden bu kodda çözmek istediğiniz konusunda biraz merak ediyorum. UDP paketinizi belirli bir IP'ye gönderiyorsanız ve bu sunucu iç ağda ise, IP yığını bu paketi doğru şekilde ilgili NIC arabirimi üzerinden otomatik olarak yönlendirmelidir. Yoksa daha fazla özledim mi? –

+0

Ayrıca, numaralandırmadaki ilk öğenin her zaman sizin tercih ettiğiniz NIC olduğundan emin olabilirsiniz - geridöngü arabirimi veya bazı egzotik 6to4 tünel arabirimi nedir? –

1

, veri göndermek için ", sistem bir tercih var ya da başka NIC kullanmak istediğinizi belirtmek gerekirse arayüzü Ancak. Kullanıldığı belirler, sen sorgulayabilir Uygun arayüzler için sistem ve kullanmak istediğiniz arayüzde bir adres bulun. "

NetworkInterFaces program aracılığıyla,
Enumeration en = NetworkInterface.getNetworkInterfaces();

Herbirini yinelemek, onunla ilişkili InetAddress'i edinebilir ve Datagram soketini oluşturmak için InetAddress'i kullanabilirsiniz.Bu soruya iyi bilgi yoktur
- yardımcı How to enumerate IP addresses of all enabled NIC cards from Java?

umut, İşte

0

kullandığım çoğunlukla tam koddur. Benim durumumda, bağlantım tarafından kullanılan IP adresi önekini biliyorum. Arabirimin adını aramanız ve bir yapılandırma dosyasında sakladığınız bir değerle karşılaştırmanız gerekebilir.

DatagramSocket yerine MulticastSocket kullanılmasına dikkat edin, böylece setNetworkInterface yöntemi istenen arabirimi bağlamak için kullanılabilir. MulticastSocket bir DatagramSocket alt sınıfı olduğundan, anahtar genellikle sorun çıkarmaz.

@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

Sadece aynı probleminiz vardı. Sorunu çözmek için acil değildi ama nihayet senin için yararlı olabilir bazı kodlar yazdım:

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

Ben kodu düzgün çalıştığından emin olmak için çıktı bir sürü kullanılan ve bunu yapmak ister bak Ben hala üzerinde çalışıyorum ama bu sorun için yeterli olabilir varsayalım

İlgili konular