dim*_*mba 22 linux networking tcp
机器是RHEL 5.3(内核2.6.18).
有时我在netstat中注意到我的应用程序有连接,当本地地址和外地址相同时建立了TCP连接.
这里同样的问题,有人报道过别人.
症状与链接中描述的相同 - 客户端连接到本地运行的服务器的端口X端口.一段时间后,netstat显示客户端已连接127.0.0.1:X
到127.0.0.1:X
怎么可能?
编辑01
同时打开导致问题(非常感谢Hasturkun).您可以在从SYN_SENT状态转换为SYNC_RECEIVED的经典TCP状态图中看到它
Omn*_*ous 13
此连接由此元组唯一标识(local address, local port #, foreign address, foreign port #)
.没有要求local address
和foreign address
甚至端口号不同(尽管这会非常奇怪).但是最多有一个TCP连接对于给定的元组具有相同的值.
当计算机连接到自身时,它的本地地址和外地地址几乎总是相同的.毕竟,"本地"方面和"外国"方实际上是同一台计算机.实际上,当发生这种情况时,您的计算机应该显示两个具有相同"本地"和"外部"地址的连接,但是反向端口号.例如:
$ ssh localhost
Run Code Online (Sandbox Code Playgroud)
将导致两个连接看起来像这样:
$ 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
Run Code Online (Sandbox Code Playgroud)
如您所见,本地地址和外部地址相同,但端口号相反.此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)
Run Code Online (Sandbox Code Playgroud)
此代码有效,因为可以打开TCP连接的一种方法是让连接的另一端尝试同时打开一个连接.这被称为同步SYN交换,链接到StackOverflow答案描述了它的内容.
我还有一篇关于使用同时进行SYN交换以通过NAT的论文,尽管在这种情况下,源和外部将完全不同.