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!
+ Sorunun güzel sunumu için 1. – deadlock