题目
TCP四次挥手过程及TIME_WAIT状态分析
信息
- 类型:问答
- 难度:⭐⭐
考点
TCP连接终止流程,四次挥手状态转换,TIME_WAIT状态作用
快速回答
TCP四次挥手是可靠终止连接的过程:
- 主动关闭方发送FIN报文
- 被动关闭方回复ACK,进入CLOSE_WAIT状态
- 被动关闭方发送FIN报文
- 主动关闭方回复ACK,进入TIME_WAIT状态
TIME_WAIT状态持续2MSL(最大报文生存时间),作用:
- 确保最后一个ACK到达
- 让旧连接的报文在网络中消失
解析
四次挥手完整流程
以客户端主动关闭为例:
- FIN_WAIT_1:客户端发送FIN报文(seq=u)
- CLOSE_WAIT:服务端收到FIN后回复ACK(ack=u+1)
- FIN_WAIT_2:客户端收到ACK后等待服务端FIN
- LAST_ACK:服务端发送FIN报文(seq=v)
- TIME_WAIT:客户端回复ACK(ack=v+1)并启动2MSL计时器
- CLOSED:服务端收到ACK后关闭连接,客户端2MSL超时后关闭
状态转换示意图
Client Server
|--- FIN ----------------------->| (FIN_WAIT_1)
|<------- ACK -------------------| (CLOSE_WAIT)
|(FIN_WAIT_2) |
|<------- FIN -------------------| (LAST_ACK)
|------- ACK ------------------->| (TIME_WAIT)
|(等待2MSL) |(CLOSED)
|(CLOSED) |TIME_WAIT关键作用
- 可靠终止:若最后一个ACK丢失,服务端重传FIN时客户端能重新响应
- 消除旧报文:2MSL(通常60-120秒)确保网络中残留报文过期
- 防止串连:避免相同四元组的新连接收到旧数据
最佳实践与常见问题
| 场景 | 处理方案 |
|---|---|
| 服务器TIME_WAIT过多 | 启用socket选项SO_REUSEADDR允许重用端口 |
| 客户端资源耗尽 | 调整内核参数net.ipv4.tcp_tw_recycle(谨慎使用) |
| 连接卡在CLOSE_WAIT | 检查应用层是否未调用close()释放连接 |
代码示例(C伪代码)
// 主动关闭方
close(socket); // 触发发送FIN
// 被动关闭方
while (recv(socket) != FIN) {...}
send_ack(); // 步骤2
// ...处理剩余数据...
send_fin(); // 步骤3扩展知识
- 同时关闭:双方同时发送FIN时,会进入FIN_WAIT_1→CLOSING→TIME_WAIT特殊路径
- MSL计算:Linux默认60秒(/proc/sys/net/ipv4/tcp_fin_timeout控制)
- RST替代FIN:异常关闭时发送RST跳过挥手过程,但可能导致数据丢失