昨天,在 hadoop 集群中调试时,我发现了一些奇怪的东西
# netstat -taupen | grep 54310
tcp 0 0 10.0.12.209:54310 10.0.12.209:54310 TIME_WAIT
您会注意到源 ip:port 与目标 ip:port 相同。这怎么可能。有人可以解释一下 tcp 层中的事情是如何工作的吗?
昨天,在 hadoop 集群中调试时,我发现了一些奇怪的东西
# netstat -taupen | grep 54310
tcp 0 0 10.0.12.209:54310 10.0.12.209:54310 TIME_WAIT
您会注意到源 ip:port 与目标 ip:port 相同。这怎么可能。有人可以解释一下 tcp 层中的事情是如何工作的吗?
这是可能的,因为有两个进程(大概来自一个 fork)。左侧是客户端(调用 bind(2) 来设置其源 IP 和端口,通常不会这样做),右侧是服务器。
这是实现IPC(进程间通信)的一种方法。
建立 TCP 连接的最常见方法是使用 3 次握手,包括:
但这不是建立 TCP 连接的唯一方法。为了建立 TCP 连接,每一方都必须发送一个 SYN,另一方必须 ACK,但不需要一方将 SYN 和 ACK 组合在一个数据包中。4 次握手同样可能,其中每个端点发送一个 SYN,然后每个端点发送一个 ACK。
这种 4 次握手的一个用例是在防火墙后面的一对主机之间建立连接。如果您在受防火墙保护的网络上运行对等应用程序,这将很有用。每个端点将发送一个 SYN 并重新传输它,直到收到响应。这意味着连接两端的防火墙将看到本地端点发送 SYN 数据包,一旦它看到这样的传出数据包,它将允许来自另一端的 SYN 和 ACK 数据包通过。(虽然这种方法实际上适用于 TCP 和 UDP,但很少用于 TCP。)
所有这一切对您的场景意味着,如果应用程序创建一个 TCP 套接字并将其绑定到本地 IP 地址和端口号,然后尝试连接到相同的 IP 地址和端口号,TCP 层将首先生成一个 SYN发送给自己的数据包,然后用也发送给自己的 ACK 响应该数据包。
结果是 TCP 套接字可以连接到自身和 TCP 层,这看起来像 4 次握手。
我不知道这种连接到自身的 TCP 套接字是否有任何有用的目的,但这就是会产生像您的情况那样的连接的原因。