Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

连接关闭与 TIME_WAIT(进阶)

复习

  • 三次握手:建立连接时同步双方状态
  • 序号与确认:双方各自维护收发进度
  • TCP 为什么需要连接:连接是双方的共同状态

本章为进阶内容,零基础读者可以跳过,不影响后续阅读。

TL;DR

  • 关闭连接也要有约定步骤,不能单方面说停就停
  • 通常需要四次挥手,因为两个方向要分别关闭
  • TIME_WAIT 让主动关闭方多等一会儿再真正消失
  • 等待是为了确认对方收到关闭确认,并让旧包消散

正文

  有始就有终。连接建立是三次握手,那结束呢?总不能一方说“我不说了”,就单方面把连接撕掉吧——另一方可能还在发数据呢。

  所以,关闭连接同样需要双方商量着来,这叫四次挥手

为什么是四次

  因为 TCP 连接是双向的:你到我这有一条数据通道,我到你也有一条。要彻底关闭,得两个方向各自关门。

  过程大致是:

  1. 一方发 FIN:“我这边没有数据要发了。”
  2. 另一方回 ACK:“知道了。”
  3. 等另一方也把数据发完,再发一个 FIN:“我这边也发完了。”
  4. 最先的一方再回 ACK:“收到,连接关闭。”

  FIN 和 ACK 一来一回,两个方向各一次,加起来就是四次。这也解释了一个现象:半关闭——某一方已经发完,另一方却还能继续发。

  对比一下:建立时为什么三次就够?因为“我要连你”和“我同意”可以合并成一步(SYN+ACK);而关闭时,对方未必立刻也想关,ACK 和它自己的 FIN 之间隔着“它还有没有话要说”,所以通常拆成两步。需要几次,取决于双方状态能不能合并。

TIME_WAIT:多等一会儿

  主动关闭连接的那一方,在发出最后一个 ACK 后,并不会立刻消失,而是进入一个叫 TIME_WAIT 的状态,静静等待一段时间(通常是两倍的最长报文寿命)。

  为什么要等?主要有两个原因:

  • 确保对方收到最后的 ACK。这个 ACK 万一丢了,对方会重发 FIN。此时如果自己已经消失,对方就会一直等不到回应。多待一会儿,就能接到重发的 FIN 并再次确认
  • 让本次连接的旧数据包在网络中消散。如果立刻用相同的地址和端口建立新连接,网络上残留的旧包可能被误当成新连接的数据,造成混乱

  等这段时间过去,旧包已经陈旧到不会再被送达,新连接才安全。

  这提醒我们:“结束”往往比“开始”更需要小心。 开始出错,大不了重来;结束出错,却可能留下收尾没做干净的麻烦。

思考题 1

  为什么关闭连接通常要四次挥手,而建立连接三次就够?

思考题 2

  TIME_WAIT 的状态,是为了解决哪两个问题?

小结

知识点

  • 关闭连接需要双向分别关闭,通常四次挥手
  • 建立时可合并 SYN 与 ACK,故只需三次
  • 主动关闭方进入 TIME_WAIT 等待
  • 等待可确保最后 ACK 被处理,并让旧包消散

参考资料

  1. Wikipedia(zh):传输控制协议:连接关闭与状态迁移
  2. Wikipedia(zh):TIME_WAIT:主动关闭连接后的等待状态

思考题答案(仅供参考)

思考题 1

  因为关闭时两个方向要各自关一次,且对方的 ACK 与它自己的 FIN 之间可能隔着“还有数据要发”,难以合并,所以通常需要四次。建立时“我想连”和“我同意”可以合进一个 SYN+ACK,故三次即可。

思考题 2

  一是确保最后那个 ACK 即使丢失,自己也能收到对方重发的 FIN 并再次确认;二是让本次连接的残留数据包在网络中彻底消散,避免它们被误当成之后同地址端口新连接的数据。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

![](https://raw.githubusercontent.com/TinySnow/computer-science-guide-resources/master/computer-science-guide/cover/计算机网络/连接关闭与 TIME_WAIT.png)

设计师 | 南国微雪