TCP四次挥手
2026/7/23大约 4 分钟
既然三次握手是为了“确认眼神”建立连接,那么**四次挥手(Four-Way Wavehand)**就是为了“体面分手”。
TCP 是全双工的(即双方都能同时收发数据),这意味着即使一方发完了数据(主动关闭),另一方可能还有数据没发完。因此,每个方向的连接都需要单独关闭。

1. 四次挥手的详细过程
第一步:主动方发起断开 (FIN)
- 动作:客户端(假设是主动方)发送一个 FIN(Finish)报文。
- 状态:客户端进入
FIN-WAIT-1状态。 - 含义:“我的数据发完了,我想关掉我的发送通道了。”
第二步:被动方确认收到 (ACK)
- 动作:服务端收到后,立刻回复一个 ACK。
- 状态:服务端进入
CLOSE-WAIT(等待关闭)状态;客户端收到后进入FIN-WAIT-2状态。 - 含义:“收到你的申请了。但我这边可能还有点数据没发完,你等我一下。”
注意:此时连接处于“半关闭”状态。客户端不能再发数据,但仍可以接收服务端发来的剩余数据。
第三步:被动方发完数据,请求断开 (FIN)
- 动作:服务端处理完所有数据后,也发送一个 FIN 报文。
- 状态:服务端进入
LAST-ACK状态。 - 含义:“好了,我的数据也发完了,我也可以关了。再见!”
第四步:主动方最后确认 (ACK)
- 动作:客户端收到 FIN 后,发送最后一个 ACK。
- 状态:客户端进入
TIME-WAIT状态,经过 2MSL(最大报文生存时间)后彻底关闭;服务端收到 ACK 后立即进入CLOSED状态。 - 含义:“好的,拜拜!我知道你也要关了。”
2. 核心疑问:为什么挥手要“四次”?
握手只要三次,是因为第二步把确认(ACK)和同步(SYN)合并了。
但在挥手时,当服务端收到客户端的 FIN,往往它还有数据在传,不能立刻关闭。所以它先回一个 ACK 表示收到了请求,等自己手头的工作彻底干完,才发 FIN。
总结:因为被动方的 ACK 和 FIN 通常是分开发送的,所以比握手多了一次。
3. 关键机制:为什么要等待 2MSL?
客户端发送完最后的 ACK 后,并不会立刻消失,而是要原地等待一段时间(通常是 2 分钟左右)。这是为了:
- 防止最后的 ACK 丢失:如果服务端没收到最后的 ACK,会重发第三步的
FIN。如果客户端直接关闭了,服务端就会收到一个RST报错,没法优雅关闭。 - 清理“残存”报文:确保本次连接中所有在网络中乱窜的数据包都彻底消失,防止这些旧数据干扰下一个使用相同端口号的新连接。
4.计时器
在 TCP 四次挥手(断开连接)的过程中,为了保证连接能够可靠地关闭并防止旧数据包干扰新连接,设计了几个关键的计时器。
最核心、最常被讨论的是 TIME_WAIT 状态下的 2MSL 计时器。
1. 2MSL 计时器 (TIME_WAIT Timer)
这是四次挥手中最重要的计时器。当主动关闭方发送完最后一个 ACK 后,会进入 TIME_WAIT 状态,并启动该计时器。
- 时长:通常为 2倍的 MSL (Maximum Segment Life,报文最大生存时间)。在 Linux 中通常硬编码为 60秒(30s + 30s)。
- 为什么要等 2MSL?
- 确认最后一个 ACK 到达:如果被动方没收到最后的 ACK,会重发
FIN。主动方在 2MSL 内如果又收到FIN,说明 ACK 丢了,需要重发。 - 让旧报文消失:防止失效的报文在网络中转了一圈后,出现在后续使用相同 IP 和端口的新连接中,造成数据混乱。
2. FIN_WAIT_2 计时器
当主动方收到对方的 ACK 进入 FIN_WAIT_2 状态后,它在等待对方发送 FIN(即对方也想关闭)。
- 目的:防止对方一直不发
FIN,导致主动方永远卡在FIN_WAIT_2状态(半关闭状态)。 - 超时处理:如果超过系统设定的时间(Linux 默认为 60s),内核会直接关闭该连接。
- 配置:可通过
/proc/sys/net/ipv4/tcp_fin_timeout修改。
3. 重传计时器 (Retransmission Timer)
在挥手的每一步,发送方(无论是发 FIN 还是发 ACK)都会启动重传计时器。
- 场景:如果主动方发出
FIN后,在 RTO(Retransmission TimeOut)时间内没收到ACK,就会重新发送FIN。 - 策略:通常采用指数退避算法(等待时间翻倍),直到重试次数达到上限。
对比表
| 计时器名称 | 所在状态 | 角色 | 核心目的 |
|---|---|---|---|
| 2MSL 计时器 | TIME_WAIT |
主动关闭方 | 确保 ACK 到达 + 清除网络残余报文。 |
| FIN_WAIT_2 计时器 | FIN_WAIT_2 |
主动关闭方 | 防止对方“赖着不走”导致连接无法释放。 |
| 重传计时器 | 任意发送阶段 | 双方 | 确保 FIN<br>或 ACK<br>报文丢失后能重新发送。 |
