2015-01-01 42 views
-3

我以前做過一個簡單的點對點聊天程序,使用UDP打孔工作,現在我試圖做類似的事情,但在使用libGDX製作的遊戲中。遊戲本身運行良好,連接在局域網上工作,但我很難嘗試使用外部連接。我明白衝孔如何UDP的工作原理如下:UDP打孔不能連接外部

如果兩個人A和B知道對方的IP地址和端口,則:

  1. A發送一個UDP包B的沖模,A的NAT一個洞,但由B的防火牆丟棄
  2. 一種用於答覆
  3. 乙等待發送一個UDP分組發送到其衝頭在它自己的NAT的孔,並通過A的防火牆去
  4. 乙等待回覆
  5. A接收乙「最初的消息,並且發送第二消息到B
  6. B接收A的消息

我的網絡代碼是在一類:

private boolean connected; 
private DatagramSocket socket; 
private DatagramPacket packet; 

private InetAddress peerIP; 

public NetworkManager(InetAddress peerIP){ 
    this.peerIP = peerIP; 
    log("Created with peer ip: " + peerIP.getHostAddress()); 
    connected = false; 
} 

@Override 
public void run(){ 
    try{ 
     log("Setting up socket"); 
     socket = new DatagramSocket(Constants.CLIENT_PORT); 
     log("Socket successfully setup"); 

     //Punch hole 
     log("Punching UDP Hole"); 
     sendBytes("one"); 

     //Receive 
     log("Waiting for peer reply"); 
     receiveBytes(3); 

     //Send second message 
     if(Arrays.equals(packet.getData(), "one".getBytes())){ 
      sendBytes("two"); 
     } 

    }catch(Exception e){ 
     log("Error connecting to peer"); 
     return; 
    } 

    log("Successfully connected"); 
    connected = true; 
} 


private synchronized void receiveBytes(int length) throws Exception { 
    packet = new DatagramPacket(new byte[length], length); 
    log("Receiving " + length + " bytes..."); 
    socket.receive(packet); 
    log("Received bytes " + packet.getData()+ " from " + packet.getAddress()); 
} 

private synchronized void sendBytes(String s) throws Exception { 
    byte[] sendBytes = s.getBytes(); 
    packet = new DatagramPacket(sendBytes, sendBytes.length, peerIP, Constants.CLIENT_PORT); 

    log("Sending " + sendBytes.length + " bytes..."); 

    socket.send(packet); 

    log("Bytes sent"); 
} 
+0

「我很難用外部連接嘗試。」不要讓我們猜測。什麼不工作>?你試圖解決什麼問題? –

+0

我試圖讓我的一些朋友來運行程序,但它似乎打孔不能正常工作,即使當我嘗試手動發送數據包 –

+0

你是什麼意思的「不能正常工作」?基本上,你只是說「它不起作用」,但不會告訴我們它不工作的方式。可以手動配置路由器讓數據包通過嗎?你的程序工作了嗎?是否有消息通過? –

回答

0

如果A和B是相同的網絡中,即如果他們在同一個局域網中,A可以連接到B,反之亦然。這裏不需要UDP Hole打孔。

但是,如果它們位於不同的網絡中,或者位於不同的NAT後面,則可嘗試使用UDP打孔實現直接連接。這裏你需要一箇中介服務器。 A和B需要ping中介服務器,這會將IP和端口號傳遞給其他相應的客戶端。

這裏最重要的一點是,並非所有的NAT都支持打孔。這取決於NAT的實施情況,這在大多數情況下都不適用於公共領域。所以即使你使用UDP Hole Punching,你也需要一箇中繼服務器作爲後備。如果沒有打孔,中繼服務器可以將消息傳遞給對方。

http://www.brynosaurus.com/pub/net/p2pnat/

此鏈接說明UDP打孔架構。

+0

您不一定需要中介服務器。請參閱此處概述部分的最後一段:http://en.wikipedia.org/wiki/UDP_hole_punching –

+0

對此問題也有廣泛的回答:http://stackoverflow.com/questions/9656198/java-udp-hole -punching-example-connecting-through-firewall?rq = 1 –

+0

優秀...這就解釋了它... –