0312游戏活动专区 SPACE


深入解析 TCP 连接状态:从 netstat 到状态转移与 TIME_WAIT 之谜

在网络编程与系统管理中,理解 TCP 连接状态至关重要。本文结合实际工具与状态图,详细剖析 TCP 连接状态的奥秘。

一、netstat -natp:直观查看 TCP 连接状态

通过 netstat -natp 命令,我们可以获取当前系统的 TCP 连接信息。图中各列含义如下:

Recv-Q:接收队列中未被应用程序读取的数据量(字节数)。Send-Q:发送队列中等待发送的数据量(字节数)。Local Address:本地地址和端口,如 127.0.0.1:6379 表示本地回环地址的 6379 端口。State:连接状态,常见的有 LISTEN(监听)、ESTABLISHED(已建立连接)、TIME_WAIT(等待超时)等。PID/Program name:占用该连接的进程 ID 和程序名(需足够权限显示所有进程)。

此命令是排查网络连接问题的基础工具,例如检查端口是否被正确监听、连接是否正常建立等。

二、TCP 状态转移图:连接的生命周期全景

图中用粗实线箭头表示客户端的正常状态变迁,粗虚线箭头表示服务器的正常状态变迁。

关键状态:

SYN_SENT:

​ SYN_SENT 是 TCP 客户端在发起连接时所处的状态。当客户端想要与服务器建立连接,它会发送一个 SYN(同步)包给服务器,之后客户端就进入 SYN_SENT 状态,此时客户端等待服务器的 SYN + ACK(同步确认)包来完成三次握手的第二步。

SYN_REVD

​ SYN_RECV 是服务器在接收到客户端的 SYN 包后所处的状态。服务器收到 SYN 包后,会发送一个 SYN + ACK 包给客户端,然后进入 SYN_RECV 状态,等待客户端的 ACK(确认)包来完成三次握手的第三步。

ESTABLISHED

​ 当 TCP 连接的三次握手完成后,客户端和服务器都进入 ESTABLISHED 状态。在这个状态下,双方可以自由地交换数据,这是 TCP 连接中数据传输的正常状态。

FIN_WAIT_1

​ 当客户端(或服务器)想要关闭连接时,它会发送一个 FIN(结束)包给对方,然后进入 FIN_WAIT_1 状态。这个状态表示发送方已经没有数据要发送了,但仍然可以接收对方的数据。此时发送方等待对方的 ACK 包来确认 FIN 包的接收。

FIN_WAIT_2

​ 当发送 FIN 包的一方收到了对方的 ACK 包后,就进入 FIN_WAIT_2 状态。在这个状态下,发送方已经确认对方收到了自己的 FIN 包,并且等待对方发送 FIN 包来关闭连接的另一半。

​ 在这个状态我们已经发出了FIN,并且另一端也已对它进行确认。除非我们在实行半关闭,否则将等待另一端的应用层意识到它已收到一个文件结束符说明,并向我们发一个FIN来关闭另一方向的连接。只有当另一端的进程完成这个关闭,我们这端才会从FIN_WAIT_2状态进入TIME_WAIT状态。

​ 这意味着我们这端可能永远保持这个状态。另一端也将处于CLOSE_WAIT状态,并一直保持这个状态直到应用层决定进行关闭。

CLOSE_WAIT

​ 当一方收到对方的 FIN 包后,会发送一个 ACK 包进行确认,然后进入 CLOSE_WAIT 状态。这个状态表示接收方已经知道对方没有数据要发送了,但自己可能还有数据要发送给对方。在发送完所有数据后,接收方需要发送一个 FIN 包给对方来关闭连接。

LAST_ACK

​ 当处于 CLOSE_WAIT 状态的一方发送了 FIN 包后,就进入 LAST_ACK 状态。在这个状态下,它等待对方的 ACK 包来确认自己的 FIN 包,一旦收到 ACK 包,连接就会完全关闭。

TIME_WAIT

​ 当发送 FIN 包的一方收到了对方的 FIN 包并发送了 ACK 包后,会进入 TIME_WAIT 状态。这个状态的持续时间通常是两倍的最大段生存期(2MSL)。设置 TIME_WAIT 状态的目的是为了确保最后一个 ACK 包能够到达对方,防止因为网络延迟等原因导致对方没有收到 ACK 包而重发 FIN 包。同时,TIME_WAIT 状态也可以避免旧的数据包干扰新的连接。

三、TCP 正常建立与终止:三次握手与四次挥手的状态演绎

三次握手建立连接:

客户端发送 SYN 包,进入 SYN_SENT 状态。服务器收到 SYN 后,发送 SYN + ACK 包,进入 SYN_RCVD 状态。客户端收到 SYN + ACK 后,发送 ACK 包,双方进入 ESTABLISHED 状态。

四次挥手关闭连接:

客户端发送 FIN 包,进入 FIN_WAIT_1 状态。服务器收到 FIN 后,发送 ACK 包,进入 CLOSE_WAIT 状态;客户端收到 ACK 后进入 FIN_WAIT_2 状态。服务器发送 FIN 包,进入 LAST_ACK 状态;客户端收到 FIN 后进入 TIME_WAIT 状态,发送 ACK 包。服务器收到 ACK 后,进入 CLOSED 状态;客户端在 TIME_WAIT 等待 2MSL 后,也进入 CLOSED 状态。

四、TIME_WAIT 状态:为何必须存在?

图中服务器多次运行出现 bind err,是由于之前连接处于 TIME_WAIT 状态,端口未完全释放。

1. TIME_WAIT 存在的原因

可靠终止连接:确保最后一个 ACK 包丢失时,被动关闭方重发的 FIN 包能被接收,完成连接关闭。避免旧数据包干扰:防止旧连接的延迟数据包(如 ACK 或数据段)被新连接(相同四元组)错误接收,保证新连接的纯净性。

2. 为何是 2MSL?

MSL(Maximum Segment Lifetime):数据包在网络中最大生存时间。2MSL 是为了覆盖两种极端情况:

ACK 包正常传输时间(≤MSL)。ACK 包丢失后,被动关闭方重发 FIN 包的传输时间(≤MSL)。

总计 2MSL 确保所有旧连接相关数据包在网络中过期,避免干扰新连接。

总结

TCP 连接状态是网络通信的基石,从 netstat 命令的直观查看,到状态转移图的理论支撑,再到 TIME_WAIT 状态的深入剖析,每一个环节都影响着网络应用的稳定性与可靠性。理解这些状态,能更好地排查网络问题,优化网络编程与系统管理。

箜篌有多少根弦
英雄杀/基本牌

友情链接