问题描述
我正在编写一个 P2P 应用程序.对等点定期 ping 主服务器以更新其当前的 IP/端口,因此当对等点想要访问另一个时,它可以向服务器询问该信息.目前,对等点使用 UPnP 来配置 NAT(用于经典家庭设置)以从外部访问.
I'm writing a P2P application. Peers regularly ping a main server to update their current IP/port, so when a peer wants to reach another one it can ask the server for that information. For now peers use UPnP to configure the NAT (for classic home setups) to be accessible from outside.
所以一切正常,除非对等方的客户端尝试访问另一个(或相同)对等方的服务器并且两者都在同一个 NAT 之后.由于在这种情况下,客户端试图从 NAT 后面访问其自己的外部"(公共)IP 地址,因此 NAT 不进行端口转发并且无法路由 IP 数据包.
So everything works, except when a peer's client tries to reach another (or the same) peer's server and both are behind the same NAT. Since in that case the client is trying to reach its own "external" (public) IP address from behind the NAT, the NAT doesn't do the port forwarding and is unable to route the IP packet.
目前我正在考虑两种解决方案:
For now I'm thinking of two solutions:
- 使用 UPnP 查询 NAT 以查看端口转发到哪个本地 IP
- 在主服务器上存储对等方的内部 IP
你能想到其他解决方案吗?主流的P2P应用都采取了哪些策略来解决这个问题?
Can you think of other solutions? What strategies do mainstream P2P applications implement to solve this problem?
推荐答案
这被称为发夹条件.并非所有路由器/NAT 都能正确解决此问题.解决方法是:
This is known as the hairpin condition. Not all router/NAT solve this properly. The solutions are:
a) 检查您的路由器/NAT 是否可以配置为启用hairpining".如果您控制部署中的所有路由器/NAT,则此解决方案有效.
a) Check whether your router/NAT can be configured to enable 'hairpining'. This solution works iff you control all router/NATs in your deployment.
b) 购买另一个允许这样做的路由器/节点.就像 a) 一样,如果您控制部署中的所有路由器/NAT,它就可以工作.
b) Buy another router/node allowing this. Just like a), it works iff your control all router/NATs in your deployment.
c) 如果可以从 UPnP 获取端口信息,这也是一个解决方案,但并非所有 Router/NAT 都知道或支持 UPnP.它并未涵盖大型部署中的所有情况.
c) If you can get obtain the port information for from UPnP, this is a solution too, but not all Router/NAT know or support UPnP. It does not cover for all cases in large deployment.
d) 使用多播来发现"LAN 上的其他节点,甚至与它们通信是解决此问题的常用方法.您需要就 IP 地址达成一致并让对等方监听.
d) Using multicasting to 'discover' other nodes on the LAN and even communicate with them is a common solution to this problem. You need to agree on an IP address and have peers listen to it.
e) 在服务器上存储私有 IP 地址也是一种解决方案,但它比解决方案 d 需要更多的服务器存储容量.还有一个超时(即数据有效性到期)需要处理.
e) Storing the private IP address on the server is a solution too, but it requires more storage capacity on the server than solution d. There is a timeout (i.e., expiration of data validity) to handle too.
f) 在对等点之间使用类似 TURN 的通信(即,节点之间的通信通过中央服务器).该解决方案坚如磐石,但在带宽消耗方面并不是最有效的.
f) Use a TURN like communication between peers (i.e., communication between nodes pass through central server). This solution is rock solid, but not the most efficient in terms of bandwidth consumption.
希望这会有所帮助.
这篇关于NAT 转换在网络内部不起作用(发夹情况)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!