跳到主要内容

TCP 四次挥手过程

· 阅读需 3 分钟
素明诚
Full stack development

四次挥手的步骤

第一次挥手:客户端发送 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_2CLOSE_WAIT
服务器 -> 客户端服务器发送 FIN,请求关闭连接-LAST_ACK
客户端 -> 服务器客户端发送 ACK,确认收到关闭请求TIME_WAITCLOSED

为什么挥手需要四次?

为了保证数据完整传输

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 连接可能耗尽这些资源,导致性能下降或无法建立新的连接。