【问题标题】:UDP Hole Punching AlgorithmUDP打孔算法
【发布时间】:2012-02-12 02:38:52
【问题描述】:

谁能举一个UDP打孔的例子?

其实我想写一个聊天程序,大家知道对方的IP就可以聊天了。但是这两台机器都将位于防火墙路由器后面。所以,我需要打个洞才能沟通。

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

【问题讨论】:

标签: sockets udp hole-punching


【解决方案1】:

简短回答:不能可靠地完成。

长答案:

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

当两个端点都位于 NAT 或防火墙之后时,要使其工作,需要两个端点大约同时向彼此发送数据包。这意味着双方都需要知道彼此的公共 IP 地址和端口号,并且需要通过其他方式相互通信。

如果程序位于 NAT 之后,则无法直接确定自己的公共 IP 地址(它只会看到其私有地址,例如 192.168.x.x)。但由于您假设相关人员知道彼此的 IP 地址,因此这些人只需输入对方的地址即可。

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

【讨论】:

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

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

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

【讨论】:

    猜你喜欢
    • 2011-06-14
    • 2014-10-17
    • 2015-02-28
    • 2019-04-11
    • 2012-11-30
    • 2019-01-13
    • 2011-06-05
    • 2013-01-29
    • 2012-02-26
    相关资源
    最近更新 更多