TCP 四次挥手过程
· 阅读需 3 分钟
四次挥手的步骤
第一次挥手:客户端发送 FIN
- 动作:客户端决定结束发送数据,向服务器发送一个带有 FIN 标志的数据包。
- 状态变迁:客户端发送 FIN 后,进入 FIN-WAIT-1 状态,等待服务器的确认(ACK)。
第二次挥手:服务器发送 ACK
- 动作:服务器收到客户端的 FIN 后,返回一个 ACK 数据包,确认序号为收到的序号加 1。
- 状态变迁:客户端接收到 ACK 后,进入 FIN-WAIT-2 状态。服务器进入 CLOSE-WAIT 状态,准备结束自己的发送。
第三次挥手:服务器发送 FIN
- 动作:服务器完成其数据的发送后,向客户端发送一个带有 FIN 标志的数据包,请求关闭连接。
- 状态变迁:服务器发送完 FIN 后,等待客户端的最终 ACK 确认,进入 LAST-ACK 状态。
第四次挥手:客户端发送 ACK
- 动作:客户端收到服务器的 FIN 后,返回一个 ACK 数据包,确认序号为收到的序号加 1。
- 状态变迁:客户端发送 ACK 后,进入 TIME-WAIT 状态,保持该状态足够的时间以确保服务器接收到 ACK。该时间通常是最大报文段生存时间(Maximum Segment Lifetime, MSL)的两倍。完成这个等待后,客户端最终转入 CLOSED 状态。
方向 | 描述 | 客户端状态 | 服务器状态 |
---|---|---|---|
客户端 -> 服务器 | 客户端发送 FIN,请求关闭连接 | FIN_WAIT_1 | - |
服务器 -> 客户端 | 服务器确认,发送 ACK 响应 | FIN_WAIT_2 | CLOSE_WAIT |
服务器 -> 客户端 | 服务器发送 FIN,请求关闭连接 | - | LAST_ACK |
客户端 -> 服务器 | 客户端发送 ACK,确认收到关闭请求 | TIME_WAIT | CLOSED |
为什么挥手需要四次?
为了保证数据完整传输
CLOSE-WAIT
等待关闭
TIME-WAIT
为了解决网络的丢包和网络不稳定所带来的其他问题,确保连接方能在时间范围内,关闭自己的连接
如何查看 TIME-WAIT 状态的链接数量?
netstat -an |grep TIMEWAIT|wc -l 查看连接数等待timewait状态连接数
为什么会 TIME-WAIT 过多?解决方法是怎样的?
- 高频短连接:如果应用频繁地建立并快速关闭连接,那么在任意时刻都可能有大量的连接处于 TIME-WAIT 状态。这种情况在使用不当的客户端-服务器通信模型中很常见,如每个请求都建立新连接的 HTTP/1.0。而 HTTP/1.1 默认支持 HTTP Keep-Alive
- 资源消耗:每个处于 TIME-WAIT 的连接都会占用服务器资源(如端口和内存),过多的 TIME-WAIT 连接可能耗尽这些资源,导致性能下降或无法建立新的连接。