我在Linux上看到了奇怪的行为,我看到远程端和本端都显示相同的IP和端口组合。以下是netstat输出
netstat -anp | grep 6102
tcp 0 0 139.185.44.123:61020 0.0.0.0:* LISTEN 3361 / a.out
tcp 0 0 139.185.44.123:61021 139.185.44.123:61021 ESTABLISHED 3361 / a.out
有人能告诉我这是否可能吗?如果是,那么可能是什么情景呢?
答案 0 :(得分:3)
连接由4元组((源IP,源端口),(目标IP,目标端口))标识,源端口和目标端口可以相同而没有任何问题。甚至可以通过一个过程建立这种联系,这将导致您看到的输出。
但是,我刚被一个令人讨厌的错误所困扰,其中客户端套接字将尝试连接到同一台机器上临时端口范围内具有端口号的服务器套接字。连接操作将重试操作,直到成功为止。
重试功能是问题:如果服务器应用程序没有运行并且随机选择的源端口与目标端口相同(这是可能的,因为目标端口在短暂范围内),客户端套接字会连接到自己(这可能会对客户端应用程序的内部逻辑造成严重破坏)。
由于客户端正在尽快进行重试,因此发生这种情况的可能发生的概率为1分,足够快。
以下Python脚本重现它:
import socket
host = 'localhost'
port = 35911
ctr = 0
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
ctr += 1
s.connect((host, port))
print "Connected to self after", ctr, "tries"
break
except socket.error, e:
print e
# Retry
答案 1 :(得分:2)
这是一个可以想象的场景。 connect的调用者可以在调用connect之前调用bind。 connect的调用者可以与listen的调用者合作,并故意绑定到比侦听端口号高1的端口号。
如果内核继续重用侦听器的套接字号,我称之为内核错误。
答案 2 :(得分:1)
当多线程服务器软件接受连接时,它通常会创建另一个套接字,它在单独的线程中与新连接的客户端通信,而原始服务器套接字仍然在原始线程中侦听新客户端。在这种情况下,两个插座的端口是相同的。所以,没有任何问题。
答案 3 :(得分:1)
这有点奇怪,称为TCP“主动/主动打开”。已打开套接字,绑定到本地端口,然后使用connect()
将其自己的地址作为目标连接到自身。
答案 4 :(得分:0)
没什么好奇的。它有63%的机会发生。你不会看到的是*两个*这样的ESTABLISHED *连接:TCP的规则是不可能的。