Wireshark 实战|TCP 四次挥手:连接是怎么优雅断开的?

大家好,我是网域小星球,一名网络工程大三学生。上一篇我们用 Wireshark 抓包看懂了 TCP 三次握手,今天我们继续探索 TCP 连接的完整生命周期 ——四次挥手,看看连接是如何优雅断开的。


一、什么是 TCP 四次挥手?

TCP 是全双工通信协议,通信双方都可以独立发送和接收数据。因此断开连接时,需要双方分别发起「关闭请求」和「确认」,总共 4 次报文交互,这就是「四次挥手」。

核心目的:

  • 确保双方都完成数据传输,避免数据丢失
  • 优雅释放连接资源,防止半打开连接造成资源浪费
  • 保证连接关闭的可靠性

通俗理解:就像挂电话时,要先说「我说完了,挂了啊」,对方回复「好的,我也说完了」,再互相确认后才能挂断。


二、抓包实战:找到四次挥手

1. 准备工作

  • 打开 Wireshark,选择当前上网网卡(WLAN)
  • 在过滤栏输入:tcp.port == 53(只显示 DNS 对应的 TCP 流量,本次抓包为 DNS 连接断开场景)
  • 浏览器访问网站后关闭标签页,触发连接断开
  • 停止抓包,在结果中找到 FIN, ACKACKFIN, ACKACK 序列

2. 定位四次挥手报文

在本次抓包中,我们选取 346-349 行 这组连续的 DNS 连接断开报文:

序号 方向 标志位 对应挥手
346 客户端 → 服务器 [FIN, ACK] 第一次挥手:客户端发起关闭请求
347 服务器 → 客户端 [ACK] 第二次挥手:服务器确认客户端关闭
348 服务器 → 客户端 [FIN, ACK] 第三次挥手:服务器发起关闭请求
349 客户端 → 服务器 [ACK] 第四次挥手:客户端确认服务器关闭

三、报文细节拆解

1. 第一次挥手:客户端 → 服务器(FIN, ACK)

  • 标志位FIN=1ACK=1
  • 关键字段
    • Source Port: 63535(客户端临时端口)
    • Dest Port: 53(服务器 DNS 端口)
    • Sequence number: 35(客户端当前序列号)
    • Acknowledgment number: 178(确认服务器最后发送的数据)
    • Flags: 0x011 (FIN, ACK)
  • 含义:客户端没有新数据要发送了,主动关闭发送通道,告知服务器「我这边发完了,准备断开连接」。

2. 第二次挥手:服务器 → 客户端(ACK)

  • 标志位ACK=1
  • 关键字段
    • Acknowledgment number: 36(确认客户端的 FIN 包,序列号 + 1)
    • Flags: 0x010 (ACK)
  • 含义:服务器收到客户端的关闭请求,回复确认「我知道了,我这边还有数据要发,发完就关」。此时客户端进入 FIN_WAIT_2 状态,等待服务器的 FIN 包。

3. 第三次挥手:服务器 → 客户端(FIN, ACK)

  • 标志位FIN=1ACK=1
  • 关键字段
    • Sequence number: 178(服务器当前序列号)
    • Acknowledgment number: 36(继续确认客户端的 FIN 包)
    • Flags: 0x011 (FIN, ACK)
  • 含义:服务器数据发送完毕,主动关闭自己的发送通道,告知客户端「我也发完了,准备断开连接」。

4. 第四次挥手:客户端 → 服务器(ACK)

  • 标志位ACK=1
  • 关键字段
    • Acknowledgment number: 179(确认服务器的 FIN 包,序列号 + 1)
    • Flags: 0x010 (ACK)
  • 含义:客户端收到服务器的关闭请求,回复确认「我知道了,连接正式关闭」。之后客户端进入 TIME_WAIT 状态,等待 2MSL 后彻底释放资源。

四、关键状态与问题解答

1. 为什么是四次挥手,不是三次?

  • TCP 是全双工通信,双方都需要独立关闭「发送通道」
  • 客户端发 FIN 后,服务器可能还有数据要传输,必须先回复 ACK,等数据发完再发 FIN
  • 如果合并为三次挥手,可能导致服务器数据未发送完就被强制断开,造成数据丢失

2. TIME_WAIT 状态是什么?

  • 客户端收到服务器的 FIN 并回复 ACK 后,会进入 TIME_WAIT 状态,持续 2MSL(最长报文段寿命)
  • 作用:
    1. 确保服务器收到最后一个 ACK 包,避免因丢包导致服务器无法正常关闭
    2. 防止旧的重复报文干扰新的连接
  • 2MSL 结束后,客户端彻底释放连接资源,进入 CLOSED 状态

3. 如果第四次挥手丢失了会怎样?

  • 服务器会重发 FIN 包,等待客户端再次确认
  • 客户端在 TIME_WAIT 状态下会持续监听,收到重传的 FIN 后再次回复 ACK
  • 2MSL 超时后,客户端和服务器都会释放资源,连接彻底关闭

五、TCP 连接生命周期总结

从建立到断开,TCP 连接会经历以下核心状态:

  1. CLOSED:初始状态,连接未建立
  2. LISTEN:服务器监听端口,等待客户端连接
  3. SYN_SENT:客户端发送 SYN,等待服务器确认
  4. SYN_RCVD:服务器收到 SYN,回复 SYN+ACK,等待客户端确认
  5. ESTABLISHED:连接建立,双方可以传输数据
  6. FIN_WAIT_1:客户端发送 FIN,等待服务器确认
  7. FIN_WAIT_2:客户端收到 ACK,等待服务器的 FIN
  8. TIME_WAIT:客户端收到服务器的 FIN,回复 ACK,等待 2MSL
  9. CLOSED:连接彻底关闭,资源释放

六、下一篇预告

下篇我们会用 Wireshark 抓包分析 UDP 协议,对比 TCP 与 UDP 的差异,看看「不可靠传输」在实际场景中的应用。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐