相对于TCP创建时三次握手,TCP关闭过程(四次挥手)涉及客户端和服务端状态的变化较复杂,其又涉及网络资源的回收细节较多,很多朋友对此有所混淆。本文将说明详细的客户端及服务端状态变迁过程。
客户端主动发起关闭来看一下客户端与服务端状态变迁过程
1. 客户端主动发起关闭
客户端:
发送 FIN 报文(请求关闭连接)。
进入 FIN_WAIT_1 状态(等待对端ACK)。
服务端:
收到 FIN 后,发送 ACK 确认。
进入 CLOSE_WAIT 状态(等待应用层关闭连接)。
2. 服务端确认FIN
客户端:
收到服务端的 ACK 后。
进入 FIN_WAIT_2 状态(等待服务端的FIN)。
服务端:
应用层调用 close() 后,发送 FIN 报文。
进入 LAST_ACK 状态(等待最后一个ACK)。
3. 服务端发起关闭(发送FIN)
客户端:
收到服务端的 FIN 后,发送 ACK 确认。
进入 TIME_WAIT 状态(等待2MSL,确保ACK到达)。
服务端:
收到 ACK 后,连接关闭。
进入 CLOSED 状态。
4. 客户端最终关闭
客户端:
在 TIME_WAIT 状态等待 2MSL(Maximum Segment Lifetime,通常30秒/1分钟)。
超时后进入 CLOSED 状态。
注意问题
- TIME_WAIT 总是出现在最后发送 ACK 的一方(不一定是初始主动关闭方)
谁发送最后一个 ACK 取决于被动关闭方是否及时响应 FIN。如果被动关闭方延迟发送自己的 FIN,它可能成为最后一个发送 ACK 的一方。
- CLOSE_WAIT 表示被动关闭方未及时关闭连接(需检查程序逻辑)
- 2MSL 等待:Windows 默认 240 秒;Linux 默认 60 秒,并可通过内核参数调整(如 net.ipv4.tcp_fin_timeout)