2013-03-06 15 views
7

Uygulama bir NAT ortamında çalışıyorsa, UPnP protokolü aracılığıyla yönlendiriciyi keşfedebilen basit bir kitaplık uygulamaya çalışıyorum. Keşif paketini yönlendiriciye göndermek için iki yol, çoklu döküm ve datagram denedim ve yönlendiriciden gelen yanıt için 1901 numaralı bağlantı noktasını dinlemeye çalıştım. Ancak kodlarda bazı problemlerim var. Aşağıdaki üç çeşit yolu denedim ve yalnızca üçüncüsü yönlendiriciden gelen yanıtı doğru bir şekilde alabilir. İlk ve ikinci yollarda neden çalışmadığına dair hiçbir fikrim yok.UPnP kullanarak yayın paketi göndererek yönlendiriciyi keşfetme çalışmıyor

Birincisi: çok satırlı paket gönderin ve yanıt için 1901 numaralı bağlantı noktasını dinleyin.

kodları:

public void discovery() throws IOException { 
    // SSDP port 
    final int SSDP_PORT = 1900; 
    final int SSDP_SEARCH_PORT = 1901; 
    // Broadcast address for finding routers. 
    final String SSDP_IP = "239.255.255.250"; 
    // Time out of the connection. 
    int TIMEOUT = 5000; 
    // Localhost address. 
    InetAddress localhost = InetAddress.getLocalHost(); 

    // Send from localhost:1901 
    InetSocketAddress srcAddress = new InetSocketAddress(localhost, SSDP_SEARCH_PORT); 
    // Send to 239.255.255.250:1900 
    InetSocketAddress dstAddress = new InetSocketAddress(InetAddress.getByName(SSDP_IP), SSDP_PORT); 

    // ----------------------------------------- // 
    //  Construct the request packet.  // 
    // ----------------------------------------- // 
    StringBuffer discoveryMessage = new StringBuffer(); 
    discoveryMessage.append("M-SEARCH * HTTP/1.1\r\n"); 
    discoveryMessage.append("HOST: " + SSDP_IP + ":" + SSDP_PORT + "\r\n"); 
    discoveryMessage.append("ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"); 
    // ST: urn:schemas-upnp-org:service:WANIPConnection:1\r\n 
    discoveryMessage.append("MAN: \"ssdp:discover\"\r\n"); 
    discoveryMessage.append("MX: 2\r\n"); 
    discoveryMessage.append("\r\n"); 
    // System.out.println("Request: " + discoveryMessage.toString() + "\n"); 
    byte[] discoveryMessageBytes = discoveryMessage.toString().getBytes(); 
    DatagramPacket discoveryPacket = new DatagramPacket(discoveryMessageBytes, discoveryMessageBytes.length, dstAddress); 

    // ----------------------------------- // 
    //  Send multi-cast packet.  // 
    // ----------------------------------- // 
    MulticastSocket multicast = null; 
    try { 
     multicast = new MulticastSocket(null); 
     multicast.bind(srcAddress); 
     multicast.setTimeToLive(4); 
     System.out.println("Send multicast request."); 
     // ----- Sending multi-cast packet ----- // 
     multicast.send(discoveryPacket); 
    } finally { 
     System.out.println("Multicast ends. Close connection."); 
     multicast.disconnect(); 
     multicast.close(); 
    } 

    // -------------------------------------------------- // 
    //  Listening to response from the router.  // 
    // -------------------------------------------------- // 
    DatagramSocket wildSocket = null; 
    DatagramPacket receivePacket = null; 
    try { 
     wildSocket = new DatagramSocket(SSDP_SEARCH_PORT); 
     wildSocket.setSoTimeout(TIMEOUT); 

     while (true) { 
      try { 
       System.out.println("Receive ssdp."); 
       receivePacket = new DatagramPacket(new byte[1536], 1536); 
       wildSocket.receive(receivePacket); 
       String message = new String(receivePacket.getData()); 
       System.out.println("Recieved messages:"); 
       System.out.println(message); 
      } catch (SocketTimeoutException e) { 
       System.err.print("Time out."); 
       break; 
      } 
     } 
    } finally { 
     if (wildSocket != null) { 
      wildSocket.disconnect(); 
      wildSocket.close(); 
     } 
    } 
} 

Sonuç: yönlendirici (aşağıdaki ekran görüntüsü olarak, Wireshark'ın tarafından sniffered) yanıt paketi, ama kod şey alma değildir. code 1 http://img705.imageshack.us/img705/6531/ssdp1.png

Kod sonucu:

Send multicast request. 
Multicast ends. Close connection. 
Receive ssdp. 
Time out. 

ikincisi: gönderme datagram paketi ve yanıt için port 1901 dinle.

Kodlar:

public void discovery() throws IOException { 
    // Ignore this part of the codes since they are the same as the first one. 
    .............. 

    // -------------------------------------------------- // 
    //  Listening to response from the router.  // 
    // -------------------------------------------------- // 
    DatagramSocket wildSocket = null; 
    DatagramPacket receivePacket = null; 
    try { 
     wildSocket = new DatagramSocket(SSDP_SEARCH_PORT); 
     wildSocket.setSoTimeout(TIMEOUT); 
     // ----- Sending datagram packet ----- // 
     System.out.println("Send datagram packet."); 
     wildSocket.send(discoveryPacket); 

     while (true) { 
      try { 
       System.out.println("Receive ssdp."); 
       receivePacket = new DatagramPacket(new byte[1536], 1536); 
       wildSocket.receive(receivePacket); 
       String message = new String(receivePacket.getData()); 
       System.out.println("Recieved messages:"); 
       System.out.println(message); 
      } catch (SocketTimeoutException e) { 
       System.err.print("Time out."); 
       break; 
      } 
     } 
    } finally { 
     if (wildSocket != null) { 
      wildSocket.disconnect(); 
      wildSocket.close(); 
     } 
    } 
} 

Sonuç: Wireshark şey almaz. Hiçbir paket portu 1900 ve 1901

Kod sonucu sniffered edilir:

Send datagram packet. 
Receive ssdp. 
Time out. 

üçüncüsü: çoklu oyuncu ve datagram paketleri göndermek ve yanıt için port 1901 dinle.

Kodlar:

public void discovery() throws IOException { 
    // Ignore this part of the codes since they are the same as the first one. 
    .............. 

    // ----------------------------------- // 
    //  Send multi-cast packet.  // 
    // ----------------------------------- // 
    MulticastSocket multicast = null; 
    try { 
     multicast = new MulticastSocket(null); 
     multicast.bind(srcAddress); 
     multicast.setTimeToLive(4); 
     System.out.println("Send multicast request."); 
     // ----- Sending multi-cast packet ----- // 
     multicast.send(discoveryPacket); 
    } finally { 
     System.out.println("Multicast ends. Close connection."); 
     multicast.disconnect(); 
     multicast.close(); 
    } 

    // -------------------------------------------------- // 
    //  Listening to response from the router.  // 
    // -------------------------------------------------- // 
    DatagramSocket wildSocket = null; 
    DatagramPacket receivePacket = null; 
    try { 
     wildSocket = new DatagramSocket(SSDP_SEARCH_PORT); 
     wildSocket.setSoTimeout(TIMEOUT); 
     // ----- Sending datagram packet ----- // 
     System.out.println("Send datagram packet."); 
     wildSocket.send(discoveryPacket); 

     while (true) { 
      try { 
       System.out.println("Receive ssdp."); 
       receivePacket = new DatagramPacket(new byte[1536], 1536); 
       wildSocket.receive(receivePacket); 
       String message = new String(receivePacket.getData()); 
       System.out.println("Recieved messages:"); 
       System.out.println(message); 
      } catch (SocketTimeoutException e) { 
       System.err.print("Time out."); 
       break; 
      } 
     } 
    } finally { 
     if (wildSocket != null) { 
      wildSocket.disconnect(); 
      wildSocket.close(); 
     } 
    } 
} 

Sonuç: iki yayın paketi başarılı gönder ve yönlendirici iki cevap olsun. code 1 http://img707.imageshack.us/img707/1607/ssdp3.png

Kod sonucu:

Send multicast request. 
Multicast ends. Close connection. 
Send datagram packet. 
Receive ssdp. 
Recieved messages: 
HTTP/1.1 200 OK 
Cache-Control: max-age=300 
Date: Wed, 06 Mar 2013 05:15:43 GMT 
Ext: 
Location: http://192.168.1.1:1780/InternetGatewayDevice.xml 
Server: POSIX UPnP/1.0 DD-WRT Linux/V24 
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1 
USN: uuid:C42C1F3F-6E63-7FFC-F982-035B355D6E76::urn:schemas-upnp-org:device:InternetGatewayDevice:1 

Receive ssdp. 
Recieved messages: 
HTTP/1.1 200 OK 
Cache-Control: max-age=300 
Date: Wed, 06 Mar 2013 05:15:43 GMT 
Ext: 
Location: http://192.168.1.1:1780/InternetGatewayDevice.xml 
Server: POSIX UPnP/1.0 DD-WRT Linux/V24 
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1 
USN: uuid:C42C1F3F-6E63-7FFC-F982-035B355D6E76::urn:schemas-upnp-org:device:InternetGatewayDevice:1 

Receive ssdp. 
Time out. 

birinci ve ikinci yolu UPnP protokolü üzerinden yönlendirici istemek için neden başarısız bir fikrin var mı? Ve neden ikinci bir şey göndermiyor gibi görünüyor?

Çok teşekkürler!

+0

+ Sorunun güzel sunumu için 1. – deadlock

cevap

1

OS + yönlendirici sabit yazılımı ile ilgili bir sorun olabilir. Güvenlik duvarınızın kapalı olduğundan emin olun.

İlk metod: Bu yöntem bilgisayarımda hiç çalışmıyor (OS X):

Send multicast request. 
Exception in thread "main" java.io.IOException: Can't assign requested address 
Multicast ends. Close connection. 
    at java.net.PlainDatagramSocketImpl.send(Native Method) 
    at java.net.DatagramSocket.send(DatagramSocket.java:676) 
    at Test.discovery(Test.java:55) 
    at Test.main(Test.java:93) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

Ancak, ben değiştirdikten sonra:

InetSocketAddress srcAddress = new InetSocketAddress(localhost, SSDP_SEARCH_PORT); 

için
InetSocketAddress srcAddress = new InetSocketAddress(SSDP_SEARCH_PORT); 

Mükemmel şekilde çalışır:

Send multicast request. 
Multicast ends. Close connection. 
Receive ssdp. 
Recieved messages: 
HTTP/1.1 200 OK 
Cache-Control: max-age=60 
Date: Sun, 04 Jan 1970 21:55:18 GMT 
Ext: 
Location: http://192.168.0.2:1780/InternetGatewayDevice.xml 
Server: POSIX UPnP/1.0 linux/5.20.61.0 
ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1 
USN: uuid:C04E066F-F351-72B6-CCCF-E98237DCB05C::urn:schemas-upnp-org:device:InternetGatewayDevice:1 


Receive ssdp. 
Time out. 

İkinci yöntem: eserler.

Üçüncü yöntem: Çalışmaları.

(yorum için çok uzun)

[değiştir] Hedefiniz istikrarlı yazılım üretmektir durumda

, ben geleneksel yolla sadık salık: https://stackoverflow.com/a/4405143

İlgili konular