用户 A 和用户 B 建立到 Control 的 TCP 连接。建立后,两个用户都会向 Control 发送一个可以联系他们的端口。我们将称用户 A 的“端口 X”和用户 B 的“端口 Y”。
控制与用户 B 共享用户 A 的端口信息,反之亦然。
用户 A 从端口 X 向端口 Y 上的用户 B 发送 UDP 数据包。用户 B 的防火墙当然会拒绝此数据包。
用户 B 从端口 Y 向端口 X 上的用户 A 发送一个 UDP 数据包。用户 A 的防火墙将在内部将此端口转发给用户 A,因为用户 A 的防火墙刚刚看到一个数据包从用户 A 通过它离开端口 X 并在端口上到达用户 B Y(并且因为它是 UDP,所以它不知道它被拒绝了),所以它假设从端口 Y 上的用户 B 到端口 X 上的用户 A 的数据包是一个响应数据包,所以它让它通过。
用户 A 在端口 Y 上从端口 X 向用户 B 发送另一个 UDP 数据包,出于同样的原因,它也被允许通过用户 B 的防火墙。
用户 A 和 B 现在可以来回发送 UDP 数据包,不再需要 Control 的参与。
这一切都取决于 NAT 类型。他们中的大多数会创建一个与私有端口不同的公共端口,并且只要您使用相同的端口,就会继续为每个 IP 使用它。对于对称 NAT,情况并非如此,但无法预测具有对称 NAT 的端口。这里有一篇关于打孔的优秀文章:http://pdos.csail.mit.edu/papers/p2pnat.pdf (2认同)