UDP打孔无法外接

Posted

技术标签:

【中文标题】UDP打孔无法外接【英文标题】:UDP hole punching can't connect externally 【发布时间】:2015-02-28 01:38:50 【问题描述】:

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

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

    A 向 B 发送一个 UDP 数据包,该数据包在 A 的 NAT 上打了一个洞,但被 B 的防火墙丢弃 A 等待回复 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");

【问题讨论】:

“我很难尝试外部连接。”。不要让我们猜测。什么不工作>?您尝试过什么来解决这些问题? 我曾尝试让一些朋友运行该程序,但即使我尝试手动发送数据包,打孔似乎也无法正常工作 “不能正常工作”是什么意思?基本上,您只是在说“它不起作用”,但没有给我们任何关于它不起作用的线索。可以手动配置路由器以让数据包通过吗?然后你的程序有效吗?有消息通过吗? 我没有尝试手动配置它们,但我知道数据包正在发送,它们很可能被对等方的防火墙丢弃。我假设我如何解释 UDP 打孔存在错误。我之前实现的几乎完全相同,但是对于一个有效的简单聊天程序,所以我仍然不明白哪里出了问题。 请给我们一些信息 - 否则我们只是猜测。除非有更多信息,否则我不会再回复了。您需要帮助我们来帮助您。 【参考方案1】:

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

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

这里需要注意的最重要一点是,并非所有 NAT 都支持打孔。这取决于 NAT 的实现,这在公共领域中大部分是不可用的。所以即使你使用 UDP Hole Punching,你也需要一个中继服务器作为后备。如果没有打孔,中继服务器可以互相传递消息。

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

此链接解释了 UDP 打孔架构。

【讨论】:

您不一定需要中介服务器。请参阅此处概述部分的最后一段:en.wikipedia.org/wiki/UDP_hole_punching 这个问题也有广泛的答案:***.com/questions/9656198/…

以上是关于UDP打孔无法外接的主要内容,如果未能解决你的问题,请参考以下文章

移动提供商无法进行 UDP 打孔

UDP打孔:无法从服务器发送到客户端

需要帮助设置用于 p2p 数据传输的 udp 打孔。无法让 STUN 工作

UDP 打孔 (c++/winsock)

UDP 打孔在非对称 NAT 上失败

UDP打孔混乱