你怎么能有一个TCP连接回同一个端口?

机器是RHEL 5.3(内核2.6.18)。

有时我注意到在netstat中我的应用程序有连接,当本地地址外地址相同时build立了TCP连接。

这里同样的问题也由别人报道。

症状与链接中描述的相同 – 客户端连接到本地运行的服务器的端口X端口。 经过一段时间netstat显示客户端连接从127.0.0.1:X127.0.0.1:X

怎么可能?

编辑01

同时打开导致问题(非常感谢Hasturkun)。 在从SYN_SENT状态转换到SYNC_RECEIVED状态的传统TCP状态图上,您可以看到它

Solutions Collecting From Web of "你怎么能有一个TCP连接回同一个端口?"

这可能是由TCP同时连接引起的( 在这篇文章中提到LKML ,请参阅这里 )。

尝试连接到动态本地端口范围内的端口(可在/proc/sys/net/ipv4/ip_local_port_range )的程序循环可能成功,而服务器不在该端口上侦听。

在足够多次的尝试中,用于连接的套接字可能被绑定到正在连接的同一个端口,由于前面提到的同时连接,成功。 你现在神奇地有一个客户端连接到自己

TCP连接由这个元组(local address, local port #, foreign address, foreign port #)唯一标识。 没有要求local addressforeign address ,甚至端口号不同(虽然这将是非常奇怪的)。 但是对于给定的元组,最多只有1个TCP连接具有相同的值。

当一台计算机连接到自己的时候,它的本地地址和外地址几乎总是一样的。 毕竟,“地方”和“外方”实际上是同一台电脑。 事实上,当这种情况发生时,你的计算机应该显示两个具有相同“本地”和“外部”地址的连接,但是反向的端口号。 例如:

 $ ssh localhost 

将导致两个连接看起来像这样:

 $ netstat -nA inet | fgrep :22 Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:56039 127.0.0.1:22 ESTABLISHED tcp 0 0 127.0.0.1:22 127.0.0.1:56039 ESTABLISHED 

正如你所看到的,本地地址和外地址是一样的,但端口号是相反的。 此TCP连接的唯一元组是(127.0.0.1, 56039, 127.0.0.1, 22) 。 没有其他的TCP连接具有这四个相同的字段。

你看到两个事实是因为你的电脑是连接的两端。 每一端都有自己的看法,哪一个是“外来的”,哪一个是“本地的”。

你甚至可以在同一个端口连接到自己,虽然这不是一个普遍的现象,但是这个规范并没有被禁止。 这是一个在Python中的示例程序,它将这样做:

 import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 56443)) s.connect(('127.0.0.1', 56443)) time.sleep(30) 

这个代码的工作原理是可以打开一个TCP连接的一种方式是让连接的另一端同时尝试打开一个连接。 这就是所谓的同步SYN交换 ,并且链接到StackOverflow答案描述了什么。

我也有一篇关于使用同步SYN交换来通过NAT的论文 ,但是在这种情况下,源代码和外来代码将完全不同。