编辑:在评论(并阅读链接页面)之后,我应该撤回我的建议。为了漂亮的图形,我没有删除它,但更改了最后一部分。
如果我理解正确,您在 NAT 防火墙后面都有两个客户端,它允许传出连接,但如果没有特别配置为这样做,则不会转发传入连接(因为他们不知道它的目的地是哪个本地主机)。
原则上,一个 TCP 连接在其整个存在期间总是连接相同的两个 IP 地址和这些地址的端口号(例如,我们有四个保持不变的数字)。在 NAT 情况下,您实际上有两个连接,但这在客户端计算机 A(也从服务器 S)中不可见:
Client A -------(LAN)------ NAT B ------ (Internet) -------- Server S
IP A IP B1 | IP B2 IP S
Port a | Port b Port s
TCP 数据包在 LAN 部分具有 [A:a / S:s](或 [S:s / A:a])地址和 [B2:b / S:s](或 [S:s / B2:b ]) 互联网部分的地址。连接由这个 [IP:port / IP:port] 四元组标识,因此如果您尝试更改四个数字中的一个,这必须是一个新连接(否则数据包将被丢弃)。
因此,如果您首先与您的服务器通话,您将无法继续与同一连接上的其他客户端通话,除非服务器正在转发内容。
UDP 数据包实际上也是如此,不同之处在于没有连接,并且 NAT 必须聪明并猜测哪个数据包是另一个数据包的答案,并因此将其转发到正确的方向。
正如评论和其他答案所指出的,这就是 NAT 可以被欺骗的地方:我们首先向另一个客户端发送一个 UDP 数据包,该数据包将被那里的 NAT 丢弃。但是随后另一个客户端发送了一个应答包,该应答包不是对传出包的真正应答(因为由于其他客户端的 NAT,这个包从未收到过),但 IP 地址和端口号匹配,它仍然会被允许通过。如果 NAT 也转换端口号,这可能会变得更加复杂。
对于 TCP,它可以类似地工作,如果两个 NAT 都没有真正保持打开的连接,而是在之前发送 SYN 时简单地转发(更改)数据包。它甚至更复杂,因为这里的 TCP 序列号也必须匹配。