TCP(传输控制协议)是互联网中一种面向连接的、可靠的、基于字节流的传输层通信协议。在TCP连接的生命周期中,数据传输完毕后,需要通过一个优雅的关闭流程来释放双方的资源,这个过程被称为TCP四次挥手(Four-Way Handshake)。四次挥手不仅确保了数据的完整性,还保证了连接的可靠终止,下面将详细解析这一过程。
1. 第一次挥手(FIN)
当某一方(我们称为A)的应用程序决定不再发送数据,并希望关闭连接时,它会向另一方(我们称为B)发送一个带有FIN标志的TCP段。这个FIN标志位表示此方向的数据传输完成。这标志着关闭连接的第一步。此时,A会进入FIN_WAIT_1状态,等待B的确认。
示例包头:[SEQ=A的序列号,ACK=期望的B的序列号+1,ACK标志=1,FIN标志=1]
2. 第二次挥手(ACK)
B收到A的FIN报文后,会发送一个确认报文给A,确认收到了关闭请求。这个确认报文包含ACK标志,并且确认序列号为A发送的FIN报文的序列号加一。B还会将自己的序列号递增,准备进入关闭状态。此时,B进入CLOSE_WAIT状态,等待应用程序关闭连接,而A则进入FIN_WAIT_2状态,等待B的连接关闭请求。
示例包头:[SEQ=B的序列号,ACK=A的序列号+1,ACK标志=1]
3. 第三次挥手(FIN + ACK)
当B的应用程序准备好关闭连接时,它会向A发送一个带有FIN标志的TCP段,表明B到A的方向上数据也已传输完毕。同时,这个报文中也会包含对A之前发送的FIN报文的ACK确认,即确认号为A的FIN报文序列号加一。此时,B进入LAST_ACK状态,等待A的最终确认。
示例包头:[SEQ=B的序列号,ACK=A的序列号+1,ACK标志=1,FIN标志=1]
4. 第四次挥手(ACK)
A收到B的FIN报文后,会发送一个ACK报文作为回应,确认收到了B的关闭请求。这个ACK报文的确认序列号为B的FIN报文序列号加一。至此,A完成了关闭流程,进入TIME_WAIT状态,等待足够的时间以确保B收到了最后的ACK报文。B在收到这个ACK后,关闭连接,进入CLOSED状态。A在等待计时结束后也将进入CLOSED状态,彻底结束连接。
示例包头:[SEQ=A的序列号,ACK=B的序列号+1,ACK标志=1]
分析说明表
| 步骤 | 描述 | 发送方状态变化 | 接收方状态变化 | 关键标志 |
|---|---|---|---|---|
| 1 | A发送FIN | A: FIN_WAIT_1 | B: - | FIN |
| 2 | B确认A的FIN | A: FIN_WAIT_2 | B: CLOSE_WAIT | ACK |
| 3 | B发送FIN + ACK | A: - | B: LAST_ACK | FIN, ACK |
| 4 | A确认B的FIN | A: TIME_WAIT -> CLOSED | B: CLOSED | ACK |
注意事项
- TIME_WAIT状态:A在最后的ACK发送后会进入TIME_WAIT状态,持续时间为2MSL(Maximum Segment Lifetime,最大报文生存时间),目的是确保网络中的延迟报文被丢弃,防止出现旧数据干扰新连接。
- CLOSE_WAIT状态:如果B的应用程序没有正确关闭连接,B会停留在CLOSE_WAIT状态,这通常意味着资源泄露,需要排查应用逻辑。
- 半关闭:在第二次挥手后,连接处于半关闭状态,即A不能再向B发送数据,但B仍可以向A发送数据,直到B也发送FIN。
综上所述,TCP四次挥手通过一系列精心设计的握手过程,确保了连接的两边都能准确无误地知道对方的意图,实现了连接的可靠关闭,是TCP协议可靠性的重要体现。


