选择UDP打孔的端口号



我有一个奇怪的问题。我有一个成功工作的c++ (boost asio) P2P应用程序,它适用于大多数NAT。问题是,当我给出初始启动端口号为1000时,它会检查1000是否空闲,否则增加1,并选择一个端口并开始握手。但是,当我有10000,20000,或任何其他巨大的端口号的穿孔不工作端口限制锥NAT。

这怎么可能?我很确定这与代码无关。最近它在我一个朋友的全锥NAT上也不起作用,但它在其他许多全锥NAT上都起作用了。原因是什么呢?是否有一些我错过了如何NAT行为?

  1. 在许多NAT实现中,都有适当的保护规则来防止一个主机占用广域网接口上的大部分端口,例如这里所描述的

  2. 根据路由器的不同,NAT表项有不同的生存期,并且总是限制多少端口可以分配给单个客户端(我看到的数字从128到4096)。

所以我认为当你到达需要使用高端口的时候,你的源IP地址的NAT表已经满了(或几乎满了)来自旧连接的条目,或者来自其他应用程序的连接,所以路由器要么决定拒绝,要么不能为你的端口适配新的NAT条目。

但是,为了确定,我会尝试在受控环境中重复此操作,收集NAT两侧的Wireshark转储并分析数据包。如果可能的话,启用路由器日志并查看它们也会很有帮助。

我知道这不是"灵丹妙药",但希望它能对你有所帮助。

不要尝试自己选择端口号。操作系统可以比你的代码做得更快更好。

将套接字绑定到端口0,并让操作系统为您选择一个可用的端口号。您没有指定使用哪种编程语言,但它通常涉及在bind()调用之后调用getsockname(),以发现将要使用的本地端口。Java和。net有等价的api来做同样的事情。

然后按照这里的所有其他步骤:https://stackoverflow.com/a/8524609/104458

不确定这是否有帮助,但您是否尝试过让一个客户端应用程序实例从1001开始,另一个从1000开始,然后都增加1。

虽然1000将在客户端B上失败,但客户端A已经尝试了1001并打了那个孔,所以希望它能工作,对吗?从理论上讲,我觉得还可以。

最新更新