挥手后,客户端为什么还要多等2分钟(TIME-WAIT)?
挥手步骤发送方含义谁关闭了通道?1Client FINClient:我没有数据要发送了。Client -> Server 通道关闭2Server ACKServer:我收到了,但我可能还有话要说。Server -> Client 通道仍开着3Server FINServer:好了,我也说完了。Server -> Client 通道关闭4Client ACKClient:我确认你已经说完,再见。连接
·

TCP的四次挥手(Four-Way Handshake)是连接终止的“闭幕仪式”,它相比三次握手要复杂,因为它涉及到双向通道的独立关闭。
核心原因:TCP连接是全双工 (Full-Duplex) 的。当一方(比如客户端)说“我没数据要给你发了”(FIN),并不意味着它也停止接收数据。它可能仍然需要接收服务器发来的最后一些数据。因此,服务器必须独立地发送一个FIN包来关闭它自己这端的发送通道。
技术解析
四次挥手的目标是释放连接,确保双方的发送和接收通道都关闭。
| 步骤 | 发送方 | 接收方 | 核心内容 | 发送方的状态变化 | 接收方的状态变化 |
|---|---|---|---|---|---|
| 1 (FIN) | 客户端 | 服务器 | 携带 FIN=1 (请求终止),Seq=U (序列号) | ESTABLISHED -> FIN-WAIT-1 | ESTABLISHED -> CLOSE-WAIT |
| 2 (ACK) | 服务器 | 客户端 | 携带 ACK=1 (确认终止),Ack=U+1 | FIN-WAIT-1 -> FIN-WAIT-2 | CLOSE-WAIT (服务器还在发送数据) |
| 3 (FIN) | 服务器 | 客户端 | 携带 FIN=1 (服务器端也要终止),Seq=W | CLOSE-WAIT -> LAST-ACK | FIN-WAIT-2 -> TIME-WAIT |
| 4 (ACK) | 客户端 | 服务器 | 携带 ACK=1,Ack=W+1 | TIME-WAIT -> CLOSED | LAST-ACK -> CLOSED |
状态变化详解
- FIN-WAIT-1 (终止等待1): 客户端已经发送了FIN包,但还没有收到服务器的确认ACK。
- CLOSE-WAIT (关闭等待): 服务器收到了客户端的FIN包,并回复了ACK。但此时服务器可能还有数据没发完,它进入等待状态,等待自己也准备好关闭发送通道。
- FIN-WAIT-2 (终止等待2): 客户端收到了服务器的ACK,它知道服务器已经知道自己要关闭了,但它还在等待服务器发送最终的FIN包。
- LAST-ACK (最后确认): 服务器发送了自己的FIN包后,进入等待客户端对这个FIN包的最终确认(ACK)。
- TIME-WAIT (时间等待): 这是最关键的状态。 客户端在发送完最后一个ACK后,不会立刻进入CLOSED状态,而是会等待一段2MSL(Maximum Segment Lifetime,最长报文段寿命)的时间。
- 目的: 确保最后一个ACK能安全到达服务器。如果服务器没收到ACK而重传FIN,客户端可以通过等待状态重新发送ACK。同时,避免这个连接的端口号被立即复用,防止“历史遗留”数据包干扰新的连接。
故事场景:双向电话会议的退场协议
假设两位外交官(Client A 和 Server B)刚刚完成了一次双向通信的电话会议。
初始状态:双方都在通话中(ESTABLISHED)。
第一次挥手 (Client A -> FIN) — “我讲完了,我要退场了”
- A 的动作: A(Client)说:“我这边没有内容要讲了,我准备挂断电话了!” (发送FIN包)
- A 的状态: 进入终止等待1 (
FIN-WAIT-1)。
第二次挥手 (Server B -> ACK) — “好的,我收到了,但你先别挂”
- B 的动作: B(Server)说:“我收到了你要关闭发送通道的请求,我确认!” (发送ACK包)
- B 的状态: 进入关闭等待 (
CLOSE-WAIT)。- 关键:B只是确认收到了A的请求,但B自己的发送通道还没有关闭!B可能还有最后一句“机密信息”没来得及说。A必须继续听着。
第三次挥手 (Server B -> FIN) — “我也讲完了,你现在可以挂了”
- B 的动作: B发现自己确实没有什么要说的了。B说:“现在,我也准备关闭我的发送通道了!” (发送FIN包)
- B 的状态: 进入最后确认 (
LAST-ACK)。
第四次挥手 (Client A -> ACK) — “收到!再见,我走了!”
- A 的动作: A收到了B的告别,最后说了一句:“收到!我确认我们都说完了,再见!” (发送ACK包)
- A 的状态: 进入时间等待 (
TIME-WAIT),等待2MSL后,彻底关闭。
为什么要TIME-WAIT (Client A 为什么不立即挂断?)
- 比喻:A发送完最后的“再见”后,他不能马上挂电话。他会继续拿着话筒,等待2分钟。
- 目的:A在等待期间,如果B没有收到A的最后一句“再见”(ACK包在网络中丢失),B会焦虑地再重说一次“再见”(重传FIN包)。A听到后,可以立刻重说一遍“再见”,确保B听到了,然后B就能安心挂断。
- 效果:保证了连接终止的可靠性,也避免了新的连接请求干扰。
故事总结:
| 挥手步骤 | 发送方 | 含义 | 谁关闭了通道? |
|---|---|---|---|
| 1 | Client FIN | Client:我没有数据要发送了。 | Client -> Server 通道关闭 |
| 2 | Server ACK | Server:我收到了,但我可能还有话要说。 | Server -> Client 通道仍开着 |
| 3 | Server FIN | Server:好了,我也说完了。 | Server -> Client 通道关闭 |
| 4 | Client ACK | Client:我确认你已经说完,再见。 | 连接彻底关闭 |
结论:
TCP的四次挥手是一个优雅的、协商式的、分段关闭的过程。它之所以是四次,是为了独立地关闭全双工连接的两个方向,确保每一方都能在自己说完话后,并且确认对方也说完话后,才正式地、安全地释放连接。
更多推荐



所有评论(0)