UDP打洞算法

20

有人能给出一个UDP打洞的例子吗?

实际上,我想写一个聊天程序,让人们在知道对方IP地址的情况下进行聊天。但是两台机器都在防火墙路由器后面。因此,我需要打洞以便进行通信。

我想要一个函数,调用该函数后将会打洞,并且未来的通信将可以轻松进行——如果这不算太过分的话 :)


1
可能是重复的问题: https://dev59.com/UWoy5IYBdhLWcg3wfOB4#8524609 - selbie
没有一个简单的函数可以解决所有的NAT穿透问题。请参见上面的链接,了解更多关于NAT穿透和P2P的讨论。 - selbie
2个回答

27

简短回答:无法可靠地完成。

长篇回答:

“打洞”指的是触发路由器的自动NAT规则以允许入站流量。当您发送UDP数据包时,路由器(通常)会创建一个临时规则,将您的源地址和端口映射到目标地址和端口,反之亦然。只有来自目标地址和端口(而没有其他地址和端口)的UDP数据包才会通过并传递回原始的源地址和端口(而没有其他地址和端口)。该规则将在几分钟内超时,如果没有活动则会被清除。

当两个端点都在NAT或防火墙后面时,要使其正常工作需要同时让双方向对方发送数据包。这意味着双方都需要知道对方的公共 IP地址和端口号,并且需要通过其他方式进行通信。

如果程序位于NAT后面,则无法直接确定其自己的公共IP地址(它只能看到其私有地址,如192.168.x.x)。但是,由于您假设涉及的人都知道对方的IP地址,因此这些人可以直接输入对方的地址。

但是真正的问题在于,程序也无法直接确定路由器在公共端口上使用的端口号。您的程序可能绑定到本地机器上的12345端口,但路由器可以将其映射到公共一侧的任何端口。(想象一下局域网中有两台计算机都从端口12345发送数据包,显然路由器必须将其中一台映射到不同的数字。)因此,即使您和对方知道绑定的本地端口号,也无法知道路由器向外界显示的端口号是多少。


14
Seth - 你很好地概述了NAT穿透的问题,但是你让它看起来像一个不可能解决的问题。但实际上,STUN、TURN、ICE和可靠的信令服务的组合可以使P2P连接非常可靠。换句话说,公共互联网上的服务器有助于节点直接连接。 - selbie
1
如果您可以可靠地到达第三方中继,那么您是正确的,问题在很大程度上会消失。@c.adhityaa实际上并没有说直接通信是必需的,所以我应该问一下。此外,如果您放宽可靠性要求,那么让两个对等方同时发送彼此相隔几秒钟的几个数据包可能会在大部分时间内起作用。我习惯于处理企业防火墙,因此我可能过于悲观,认为网络允许的内容太少了。 - Seth Noble

8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接