TCP断开连接四次挥手

TCP 四次挥手是 TCP 协议断开连接的标准流程。因为 TCP 是一种全双工通信(双方可以同时收发数据)的协议,所以在断开连接时,通信双方的发送通道必须各自独立关闭,总共需要 4 次报文交互。

假设由客户端主动发起关闭请求,服务端被动响应,以下是四次挥手的详细步骤:

🌊 TCP 四次挥手完整流程

复制代码
客户端(主动断)                 服务端(被动断)
  ESTABLISHED                  ESTABLISHED
      |                            |
1.发 FIN=1 seq=u  -------------->  |
    进入 FIN_WAIT1                 |
                                   |
2.  <------------ ACK=1 ack=u+1  收FIN
                                   进入 CLOSE_WAIT
客户端收到ACK → 进入 FIN_WAIT2
                                   服务端继续发剩余数据
      |                            |
3.  <------------ FIN=1 seq=v     数据发完,主动关自己写通道
                                   进入 LAST_ACK
      |                            |
4.发 ACK=1 ack=v+1 --------------> |
进入 TIME_WAIT                     收到ACK → 进入 CLOSED
等待2MSL后客户端最终 CLOSED

第 1 次挥手:主动关闭方发送 FIN 报文

  • 动作 :客户端数据发送完毕,向服务端发送一个 FIN=1 的报文,表示"我没有数据要发了,请求关闭我这一侧的连接"。
  • 状态变化 :客户端从 ESTABLISHED(已建立连接)转变为 FIN_WAIT_1(等待终止)。

第 2 次挥手:被动关闭方回复 ACK

  • 动作 :服务端收到 FIN 后,立即回复一个 ACK 确认报文,表示"我知道你要关闭了"。
  • 状态变化 :服务端从 ESTABLISHED 转变为 CLOSE_WAIT(等待关闭);客户端收到确认后,从 FIN_WAIT_1 转变为 FIN_WAIT_2。
  • 注意:此时连接处于**半关闭(Half-Close)**状态。客户端不能再发数据,但可以接收数据;服务端如果还有剩余数据没发完,可以继续发给客户端。

第 3 次挥手:被动关闭方发送 FIN 报文

  • 动作 :当服务端的数据也全部发送完毕后,它会向客户端发送一个 FIN=1 的报文,表示"我也发完了,现在请求关闭我的发送通道"。
  • 状态变化 :服务端从 CLOSE_WAIT 转变为 LAST_ACK(最后确认)。

第 4 次挥手:主动关闭方回复 ACK

  • 动作 :客户端收到服务端的 FIN 后,回复最后一次 ACK 确认报文,表示"我知道了,连接正式关闭"。
  • 状态变化 :客户端进入 TIME_WAIT(时间等待)状态,等待一段时间后才会彻底释放资源;服务端收到这个 ACK 后,立刻进入 CLOSED(关闭)状态。

💡 核心问题解析

为什么握手是 3 次,而挥手是 4 次?

这是面试中非常经典的问题,核心原因在于 TCP 的全双工特性 以及 ACK 与 FIN 报文的分离:

  • 三次握手时:服务端收到客户端的连接请求(SYN)后,可以立刻把"同意连接"(ACK)和"我也要连接"(SYN)合并在同一个报文里发回去,节省了一次交互。
  • 四次挥手时 :当服务端收到客户端的关闭请求(FIN)时,它可能还有部分数据没有传输完成,不能立刻关闭自己的发送通道。因此,服务端必须先单独回复一个 ACK 告知"收到了",等自己真正处理完所有数据后,再单独发送一个 FIN 来请求关闭。这就导致无法合并,必须进行 4 次交互。
为什么主动关闭方最后要进入 TIME_WAIT 状态并等待 2MSL?

主动关闭方在发出最后一个 ACK 后,不会立刻关闭,而是会等待 2MSL(最长报文寿命的两倍)的时间,主要有两个作用:

  1. 保证最后一个 ACK 到达对方 :如果这个最后的 ACK 在网络中丢失了,服务端会因为超时重传第 3 次挥手的 FIN 报文。处于 TIME_WAIT 状态的客户端就能再次收到并重发 ACK,确保服务端能正常关闭。
  2. 防止旧连接的报文干扰新连接:等待 2MSL 可以让本次连接中所有滞留在网络中的残留报文自然失效消失,避免它们跑到下一次新建的连接中造成数据混乱。
  3. Linux 默认 MSL=30s,2MSL=60秒

总结:

  • 主动方:ESTABLISHED → FIN_WAIT1 → FIN_WAIT2 → TIME_WAIT → CLOSED
  • 被动方:ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
相关推荐
威联通网络存储13 分钟前
TS-h1283XU-RP 在医药批记录与检验场景的部署
网络·python
木子n110 小时前
车载以太网与SOME/IP服务化通信实战-01.从字节到服务:SOME/IP报文解析与四通道开销账
网络·网络协议·tcp/ip·车载以太网·some/ip
Escalating_xu11 小时前
【C 语言】数据在内存中的存储:补码、大小端、整型陷阱与 IEEE 754 全解析
java·c语言·网络
爱跳舞的烤冷面12 小时前
Linux篇——网络编程
网络
Knight_AL13 小时前
基于 Netty 实现的 WebSocket 服务端
网络·websocket·网络协议
wuyk55514 小时前
《WiFi 嵌入式物联网开发全套实战》| 第 31 章 休眠唤醒 WiFi 断连、时间同步、网络恢复机制
网络·物联网·php
沫璃染墨14 小时前
从零入门计算机网络系列(一):计算机网络初识——从网络发展史到TCP/IP协议》
linux·网络·网络协议·tcp/ip·计算机网络
王大傻092815 小时前
堆叠注入(Stacked Queries Injection)详解:原理、利用与防御
服务器·网络·数据库·web安全·网络安全
艾芯微科技15 小时前
钰泰 ETA5055V330DD1E|SOT-223 3.3V LDO,低压差、大电流线性稳压选型分享
网络·单片机·嵌入式硬件·集成测试·51单片机
bigcarp15 小时前
安卓模拟器MUMU+tcpdump抓包Socket协议流量
服务器·网络·tcpdump