Python套接字NAT端口地址

时间:2016-08-09 00:46:21

标签: python sockets nat

我在NAT后面有一个客户端套接字,我想获取进程使用的本地端口号。

为了说明我的问题,这是一个简单的例子。

假设我使用以下代码创建服务器:

welcome_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
welcome_socket.bind(("", 1500))
welcome_socket.listen(5)

然后我听取传入的连接:

(client_socket, address) = self.welcome_socket.accept()

我使用以下代码从客户端(NAT后面)连接:

sock = socket.create_connection(("server_address", 1500))

这是我有点困惑的地方。

我在服务器端获得的地址具有客户端所连接的WiFi网络的公共地址(我期望),根据我对NAT的理解,某些端口号应与实际端口号不同由客户使用,用于地址转换。

但是,如果我在客户端上使用了getsockname()函数,我将得到与服务器给出的端口号相同的端口号。

返回代码中的示例。

在服务器上:

client_socket.getpeername()
>>> ('WiFi_address', 4551)

在客户端:

sock.getsockname()
>>> ('local_address', 4551)

因此,即使客户端位于NAT后面,两个端口号都是相同的。情况怎么样?我误解了NAT是如何工作的吗?或者是否有另一个命令来获取客户端套接字绑定的物理地址?

任何见解都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

路由器可能正在使用端口地址转换(或one-to-many NAT)。维基链接进一步引用

  

PAT尝试保留原始源端口。如果这个源端口   已经使用,PAT分配第一个可用的端口号   从适当的端口组0-511,512-1023开始,或   1024-65535。当没有更多端口可用时,还有更多端口   如果配置了一个外部IP地址,PAT将移至下一个IP   尝试再次分配原始源端口的地址。这个   进程一直持续到可用端口和外部IP耗尽为止   地址。

这应该是您在服务器上看到端口4551的原因。

This link也应该有助于澄清NAT和PAT之间的区别)