如何从NAT路由器后面区分连接?

背景:我有一个用PHP编写的非常简单的服务器程序。 这主要是工作,但只有每个站点不超过一个客户端。

问题:

  1. NAT路由器(典型的SOHO路由器)如何知道哪个内部客户端返回stream量?
  2. 我可以使用什么方法来区分NAT路由器后面的多个客户端?

NAT路由器会将出站UDP数据包的源orig-ip:orig-port元组重写为nat-i​​p:nat-port,并在orig-ip:orig-portnat-i​​p:nat-port之间维护一个关系表,这样UDP答案以nat-i​​p:nat-port作为目的地的数据包可以映射回orig-ip:orig-port目的地。 有关NAT实现如何处理事情的详细信息,请查看Linux中如何实现连接跟踪 。

如果您的实现不允许更改客户端端口号,则无法保证在NAT路由器后面工作。 它可能在为一个客户端工作,因为许多实现尝试使用与原始数据包相同的源端口号(如果可用),所以nat-port将等于第一个客户端连接的原始端口 。 但是当这个端口变得不可用时,随后的尝试将不可避免地导致nat-port不同于orig-port的情况

因此,您需要区分不同客户端的基本“关键”是客户端的源UDP端口。 您的服务器聊天应用程序需要生成UDP数据包,并将其发送到与发起聊天连接的客户端数据包所在的目标端口相同的目标端口,从而创build与build立的TCP会话几乎相同的情况。

192.168.1.xnetworking的路由器为每个出站连接分配一个互联网端唯一的源端口。 当路由器得到答复时,它会查找数据包发送到其NAT表中的端口,并告诉它在LAN端将哪个IP和端口作为目的地。

当数据包从LAN侧发送到Internet侧时,路由器检查其NAT表。 如果没有该本地源IP地址,本地源端口,远程IP地址和远程端口对应的条目,则创build一个。 新的目标端口地址被分配。 数据包被发送到互联网,源IP被重写到路由器的互联网IP,并且源端口被重写到分配的源端口。

在Internet侧收到报文时,路由器检查NAT表中的目的端口。 如果没有对应于该远程IP和目的地端口的条目,则该分组被丢弃(除非路由器正在做的其他事情需要它)。 如果是,则将目标IP地址更改为正确的本地IP地址,将目标端口更改为原始本地源端口,然后将数据包发送到LAN。

您所说的“唯一ID”是本地计算机要与之通信的远程IP地址与路由器select的本地源端口的组合。