TCP 四次挥手详解

TCP 四次挥手详解:为什么必须四次?为什么需要 TIME_WAIT?

1. 四次挥手的必要性

TCP 是全双工协议,数据可以双向独立传输。因此,关闭连接需要分别关闭 客户端→服务端服务端→客户端 两个方向的数据流。四次挥手的设计确保了双方都能安全、有序地终止连接。

四次挥手流程:

  1. 第一次挥手(FIN)
    • 主动关闭方(如客户端)发送 FIN=1, seq=u,表示自己不再发送数据,进入 FIN_WAIT_1 状态。
  2. 第二次挥手(ACK)
    • 被动关闭方(如服务端)收到 FIN 后,回复 ACK=1, ack=u+1,进入 CLOSE_WAIT 状态。
    • 客户端收到 ACK 后进入 FIN_WAIT_2 状态(此时 客户端→服务端方向已关闭,但服务端仍可发送数据)。
  3. 第三次挥手(FIN)
    • 服务端完成数据发送后,发送 FIN=1, seq=v, ack=u+1,进入 LAST_ACK 状态。
  4. 第四次挥手(ACK)
    • 客户端收到 FIN 后,回复 ACK=1, ack=v+1,进入 TIME_WAIT 状态,等待 2MSL 后关闭连接。
    • 服务端收到 ACK立即关闭连接

2. 为什么不能合并为三次挥手?

如果尝试合并第二次和第三次挥手(即服务端在收到 FIN 后立即回复 FIN+ACK),会导致:

  • 数据丢失风险:服务端可能仍有未发送完的数据,强制关闭会导致数据不完整。
  • 破坏半关闭(Half-Close):TCP 允许一方在停止发送后仍能接收数据(如客户端关闭写入但仍可读服务端的响应)。

因此,四次挥手是可靠关闭的最小交互次数。


3. 为什么客户端需要 TIME_WAIT 状态?

客户端(主动关闭方)在发送最后一个 ACK 后进入 TIME_WAIT,等待 2MSL(Maximum Segment Lifetime) 后才关闭。原因:

(1) 确保最后一个 ACK 到达服务端
  • 如果客户端的 ACK 丢失,服务端会重传 FIN
  • 处于 TIME_WAIT 的客户端能响应重传的 FIN,重新发送 ACK,避免服务端卡在 LAST_ACK 状态。
(2) 避免旧连接的数据包干扰新连接
  • 网络中可能残留旧连接的延迟报文(相同四元组:源/目的 IP + 端口)。
  • TIME_WAIT 确保所有旧报文在网络中消亡(MSL 是报文最大生存时间),防止新连接收到脏数据。

为什么是 2MSL?

  • 1MSL 确保 ACK 到达服务端 + 1MSL 确保服务端重传的 FIN 到达客户端。
  • 通常 MSL 为 30 秒(Linux)或 2 分钟(Windows),因此 TIME_WAIT 持续 60 秒或 4 分钟。

4. 常见误解澄清
  1. "服务端为什么能立即关闭,而客户端要等待?"

    • 服务端是被动关闭方,收到最后一个 ACK 后无需等待,因为它的 FIN 已被确认。
    • 客户端是主动关闭方,需确保 ACK 不丢失(否则服务端会一直重传 FIN)。
  2. "可以优化为三次挥手吗?"

    • 不能!合并 ACKFIN 会牺牲可靠性(如服务端未发送完的数据会被丢弃)。
  3. "TIME_WAIT 是多余的?"

    • 不是!它是 TCP 可靠性的关键设计,避免连接混乱和资源泄漏。

5. 总结
  • 四次挥手 是 TCP 全双工特性的必然要求,确保双向数据流独立关闭。
  • TIME_WAIT 是主动关闭方的容错机制,解决 ACK 丢失和旧报文干扰问题。
  • 设计目标:在网络不可靠的条件下,实现连接的可靠释放

通过四次挥手和 TIME_WAIT,TCP 实现了优雅而安全的连接终止。

相关推荐
席万里2 分钟前
关于Go的init函数执行顺序#黑魔法
开发语言·网络·golang
Evand J16 分钟前
【TCN与LSTM例程】TCN(时间卷积网络)与LSTM(长短期记忆)训练单输入单输出,用于拟合一段信号,便于降噪。MATLAB
网络·人工智能·matlab·lstm
橘子真甜~28 分钟前
C/C++ Linux网络编程6 - poll解决客户端并发连接问题
服务器·c语言·开发语言·网络·c++·poll
zwm_yy1 小时前
服务器检查内存爆满
运维·服务器
摩尔元数1 小时前
2025,服务器通信MES厂商谁主沉浮?
运维·服务器
last demo1 小时前
nfs服务器
linux·运维·服务器·php
翼龙云_cloud2 小时前
阿里云渠道商:自建或RDS怎么迁移到阿里云PolarDB?
运维·服务器·阿里云·云计算
牢七2 小时前
12345W
网络
q***76662 小时前
RustDesk搭建公网中继服务器远控内网机器(完整版)
运维·服务器
淼_@淼3 小时前
pytest简介
运维·服务器·pytest