首页 文章

UDP打孔无法外部连接

提问于
浏览
-3

我之前使用UDP打孔工作制作了一个简单的点对点聊天程序,现在我正在尝试做类似的事情但是在使用libGDX制作的游戏中 . 游戏本身运行良好,连接在局域网上工作,但我很难尝试外部连接 . 我理解UDP穿孔的工作原理如下:

如果A人和B人都知道对方的IP地址和端口,那么:

  • A向B发送UDP数据包,该数据包在A 's NAT but is dropped by B'的防火墙中打孔

  • 等待回复

  • B向A发送UDP数据包,该数据包在自己的NAT中打出一个洞并通过A的防火墙

  • B等待回复

  • A接收B的初始消息并向B发送第二条消息

  • 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");
}

1 回答

  • 0

    如果A和B都在同一网络中,即如果它们在同一个LAN中,则A可以连接到B,反之亦然 . 这里不需要UDP Hole打孔 .

    但是如果它们位于不同的网络中,或者位于不同的NAT后面,则可以尝试使用UDP打孔来实现直接连接 . 在这里,您需要一个中介服务器 . 并且A和B需要ping中介服务器,它将IP和端口号传递给其他相应的客户端 .

    这里要注意的最重要的一点是并非所有NAT都支持打孔 . 这是NAT实现,主要是在公共领域不可用 . 因此,即使您使用UDP打孔,您也需要一个中继服务器作为后备 . 如果没有打孔,中继服务器可以将消息传递给彼此 .

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

    此链接说明了UDP Hole Punching架构 .

相关问题