2013-03-06 8 views
7

मैं एक साधारण लाइब्रेरी को लागू करने की कोशिश कर रहा हूं जो यूपीएनपी प्रोटोकॉल के माध्यम से राउटर को खोज सकता है यदि एप्लिकेशन एनएटी पर्यावरण में चल रहा है। मैंने राउटर में खोज पैकेट भेजने के लिए दो तरीकों, बहु-कलाकार और डेटाग्राम की कोशिश की है, और राउटर से प्रतिक्रिया के लिए पोर्ट 1 9 01 को सुनने की कोशिश की है। हालांकि, मुझे कोड के साथ कुछ समस्याएं आई हैं। मैंने निम्नलिखित तीन प्रकार के तरीकों की कोशिश की, और केवल तीसरा राउटर से प्रतिक्रिया प्राप्त कर सकता है। मुझे नहीं पता कि यह पहले और दूसरे तरीकों से क्यों काम नहीं कर रहा है।यूपीएनपी का उपयोग करके ब्रॉडकास्ट पैकेट भेजकर राउटर की खोज

पहला: मल्टी-कास्ट पैकेट भेजें, और प्रतिक्रिया के लिए पोर्ट 1 9 01 को सुनें।

कोड:

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(); 
     } 
    } 
} 

परिणाम: रूटर प्रतिक्रिया पैकेट (निम्न स्क्रीनशॉट के रूप में, Wireshark द्वारा sniffered) करता है, लेकिन कुछ भी कोड प्राप्त नहीं होता है। code 1 http://img705.imageshack.us/img705/6531/ssdp1.png

कोड परिणाम:

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

दूसरा एक: भेजने आंकड़ारेख पैकेट, और प्रतिक्रिया के लिए पोर्ट 1901 सुन।

कोड:

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(); 
     } 
    } 
} 

परिणाम: Wireshark कुछ भी नहीं मिलता है। कोई पैकेट पोर्ट 1900 और 1901

कोड परिणाम पर sniffered है:

Send datagram packet. 
Receive ssdp. 
Time out. 

तीसरा: बहु कलाकारों और आंकड़ारेख पैकेट भेजने, और प्रतिक्रिया के लिए पोर्ट 1901 सुन।

कोड:

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(); 
     } 
    } 
} 

परिणाम: दो प्रसारण पैकेट सफल होने भेजें, और रूटर से दो प्रतिक्रियाओं मिलता है। code 1 http://img707.imageshack.us/img707/1607/ssdp3.png

कोड परिणाम:

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. 

वहाँ किसी भी विचार क्यों पहली और दूसरी तरह से UPnP प्रोटोकॉल के माध्यम से रूटर का अनुरोध करने में विफल रहा है? और दूसरा क्यों कुछ नहीं भेज रहा है?

बहुत धन्यवाद!

+0

+ प्रश्न की अच्छी प्रस्तुति के लिए 1। – deadlock

उत्तर

1

मुझे लगता है कि यह ओएस + राउटर फर्मवेयर से संबंधित समस्या हो सकती है। सुनिश्चित करें कि आपका फ़ायरवॉल बंद है।

पहले Methot: इस विधि अपने कंप्यूटर पर बिल्कुल काम नहीं करता है (ओएस एक्स):

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) 

हालांकि, के बाद मैं बदलने के लिए:

InetSocketAddress srcAddress = new InetSocketAddress(localhost, SSDP_SEARCH_PORT); 

को
InetSocketAddress srcAddress = new InetSocketAddress(SSDP_SEARCH_PORT); 

यह पूरी तरह से अच्छी तरह से काम करता है:

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. 

दूसरी विधि: काम करता है।

तीसरा विधि: कार्य करता है।

(भी टिप्पणी के लिए लंबे समय तक)

[संपादित करें]

मामले में अपने लक्ष्य को स्थिर सॉफ्टवेयर का उत्पादन होता है, मैं परंपरागत तरीके से चिपक recommand होगा: https://stackoverflow.com/a/4405143

संबंधित मुद्दे