2017-07-06 2 views
0

Es gibt zwei Groovy-Subprogramme, die sich untereinander über einfache UDP-Sockets senden. Sie erhalten die Nachrichten erfolgreich, wenn sie an 127.0.0.1 gesendet werden. Die Nachrichten werden jedoch nicht empfangen, wenn sie an die öffentliche IP-Adresse gesendet werden (die Maschine befindet sich hinter NAT).Warum UDP-Lochung funktioniert nicht für öffentliche IP-Adresse?

Warum ist das Loch nicht gestanzt? Und wie behebt man das?

Ich habe versucht, einen öffentlichen STUN-Server über eine Java-Bibliothek früher abzufragen, aber es antwortete mir mit der gleichen öffentlichen IP-Adresse, so dass ich wtfismyip.com hier verwende.

class GroovyTest { 

static String PUBLIC_IP = new URL('https://wtfismyip.com/text').text.trim() 
//static String PUBLIC_IP = '127.0.0.1' // works fine 

static void main(String[] args) { 
    runInstance(11111, 22222) 
    runInstance(22222, 11111) 
} 

static void runInstance(int thisPort, int anotherPort) { 
    def socket = new DatagramSocket(thisPort) 
    Thread.start { 
     // message listener 
     byte[] buf = new byte[1024] 
     while (true) { 
      DatagramPacket packet = new DatagramPacket(buf, buf.length); 
      socket.receive(packet); 
      InetAddress remoteAddr = packet.getAddress(); 
      int remotePort = packet.getPort(); 
      String sentence = new String(packet.getData(), 0, packet.length); 
      println("server-$thisPort: received [$sentence] from ${remoteAddr.hostAddress}:${remotePort}") 
     } 
    } 
    Thread.start { 
     // message sender 
     while (true) { 
      println("client-$thisPort: sending to ${PUBLIC_IP}:${anotherPort}...") 
      byte[] buf = ("Hello " + System.currentTimeMillis()).bytes 
      DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getByName(PUBLIC_IP), anotherPort) 
      socket.send(packet) 
      Thread.sleep(2000) 
     } 
    } 
} 

} 
+2

'neue URL ('https://wtfismyip.com/text') .text.trim()' - wirklich? –

+0

@shmosel Oh Groovy –

+1

https://stackoverflow.com/a/8524609/104458 – selbie

Antwort

0

Ihr Problem ergibt sich aus der Tatsache, dass die IP-Adresse von wtfismyip zurückgegeben wird, ist die IP-Adresse des Routers in Ihrem Netzwerk, die auf Ihrem Computer nicht zugeordnet ist. Wenn Sie versuchen, ein Datagramm an die öffentliche IP-Adresse Ihres Routers zu senden, erhalten Sie wahrscheinlich eine ICMP Destination Unreachable-Fehlermeldung von Ihrem Router. Wenn Sie dieses Verhalten benötigen, verfügt Ihr Router möglicherweise über einige Portweiterleitungsfunktionen, die eingehenden UDP-Datenverkehr an Ihre lokale IP-Adresse weiterleiten können.

0

Ich habe einfach erfolgreich hinter einem NAT-Router UDP-Pakete zu antworten, die Adresse und Port-Details aus dem UDP-Paket nehmen wir reagieren auf ...

DatagramSocket socket = new DatagramSocket(port); 
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length); 
socket.receive(receivePacket); 

DatagramPacket sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, 
    receivePacket.getAddress(), receivePacket.getPort()); 
socket.send(sendPacket); 

Der Code ist robuster, dass Es spielt keine Rolle, woher das Paket stammt oder welche Adressumsetzung auf dem Weg stattgefunden hat. Es wird immer an den richtigen Ort antworten.

Ich habe auch bemerkt, dass Sie zwei verschiedene Portnummern verwenden. "thisPort" und "anotherPort". Soweit ich weiß, funktioniert das Lochen nur, wenn Sie auf dieselbe Portnummer antworten. Dies ist aus Sicherheitsgründen sinnvoll.

Der marine Roboter auf meinem Kopf, in meinem Avatar dargestellt, verwendet diese UDP Stanztechnik Loch.

Verwandte Themen