UDP打孔算法

时间:2012-01-17 09:23:20

标签: sockets udp hole-punching

任何人都可以举一个UDP打孔的例子吗?

实际上,我想写一个聊天程序,当人们知道对方的IP时,人们可以聊天。但这两台机器都将在防火墙路由器后面。所以,我需要打个洞才能沟通。

我想要一个功能,这样在调用函数时,一个洞就会被打孔,未来的通信会很容易进行 - 如果这不是太多要求:)

2 个答案:

答案 0 :(得分:18)

简答:它无法可靠地完成。

长答案:

“打孔”是指触发路由器的自动NAT规则以允许入站流量。当您发送UDP数据包时,路由器(通常)会创建一个临时规则,将源地址和端口映射到目标地址和端口,反之亦然。从目标地址和端口(而不是其他)返回的UDP数据包将传递到原始源地址和端口(而不是其他)。在几分钟不活动后,此规则将超时。

当两个端点都位于NAT或防火墙后面时,要使其工作将要求两个端点几乎同时向另一个端点发送数据包。这意味着双方都需要了解彼此的公共 IP地址和端口号,并需要通过其他方式与彼此进行通信。

如果程序位于NAT后面,它无法直接确定自己的公共IP地址(它只会看到其私有地址,例如192.168.x.x)。但是既然你假设所涉及的人都知道对方的IP地址,那么那些人只能输入对方的地址。

但真正的问题是程序无法直接确定路由器在公共端使用的端口号。您的程序可能绑定到本地计算机上的12345,但路由器可以将其映射到公共端的几乎任何端口。 (想象一下,本地网络上的两台计算机都从端口12345发出,显然路由器必须将其中一台计算机映射到不同的号码。)因此,即使您和人类可能知道您绑定的本地端口号,也是如此。无法知道路由器将向世界显示的端口号。

答案 1 :(得分:7)

Lidgren的网络库内置了此功能。将库添加到应用程序后,您将实例化NetServer,连接两个NetClient,并调用NetServer.Introduce()。

链接到Lidgren:https://github.com/lidgren/lidgren-network-gen3