轻松理解 TCP 三次握手与四次挥手

TCP 建连要三次握手,断连却要四次挥手,很多人背下来了却说不清为啥。这篇用大白话加图示把它讲透:三次握手怎么确认双方收发都正常,四次挥手为啥比握手多一步,重点回答“连接三次、关闭四次”这个经典问题。

面试被问 TCP 三次握手,我早年是能背的,但一追问“为啥连接三次、关闭却要四次”,就卡壳了。

背下来和真懂,中间差着一层。这篇我们不背流程,用大白话加图示把它捋顺,重点搞明白那个经典问题:为什么连接三次握手,关闭要四次挥手。

先打个电话的比方

直接讲 SYN、ACK 这些词容易劝退,我们先拿打电话类比一下。

两个人要通电话,得先确认一件事:我说的你能听见,你说的我也能听见。

只有双向都通了,这通电话才聊得下去。

TCP 建连干的就是这事,它要确认双方的“收”和“发”都正常,才敢开始传数据。

记住这个“确认双向都通”的核心诉求,握手几次的道理就藏在里面。

三次握手在干嘛

先约定两个词,别怕,就俩:

  • SYN:请求建立连接的信号,相当于“喂,能听见吗”
  • ACK:确认收到的信号,相当于“嗯,听见了”

三次握手的过程,画出来是这样:

客户端                          服务端
  |                              |
  |  ①  SYN  “喂,能听见吗”      |
  | ---------------------------> |
  |                              |
  |  ②  SYN + ACK  “能听见,你呢”  |
  | <--------------------------- |
  |                              |
  |  ③  ACK  “我也能听见”         |
  | ---------------------------> |
  |                              |
  |      连接建立,开始传数据      |
​

一步步拆:

  • 第一次:客户端发 SYN,等于问“喂,能听见吗”
  • 第二次:服务端回 SYN+ACK,等于说“能听见(ACK),你那边能听见吗(SYN)”
  • 第三次:客户端再回 ACK,等于说“我也能听见”

为什么非得三次,两次不行?

关键在于要双向确认。我们数一下每一步各自确认了什么:

  • 第一次之后,服务端知道了:客户端的“发”和自己的“收”是好的
  • 第二次之后,客户端知道了:双向都通了(我发的你收到并回了)
  • 第三次之后,服务端才知道:自己的“发”和客户端的“收”也是好的

看出来了吗?如果只握两次,到第二次结束时,服务端并不确定客户端到底能不能收到自己的消息。

非得等第三次那个 ACK 回来,服务端才敢确认“我发的话对面也收得到”,双向这才真正确认齐活。

所以三次是确认双向通道都通的最小次数,少一次都不够。

四次挥手在干嘛

再加一个词:

  • FIN:请求关闭连接的信号,相当于“我这边说完了,要挂了”

关闭连接的过程,画出来是这样:

客户端                          服务端
  |                              |
  |  ①  FIN  “我说完了,要挂了”    |
  | ---------------------------> |
  |                              |
  |  ②  ACK  “知道了,你等等”      |
  | <--------------------------- |
  |            (服务端可能还有话没说完)|
  |                              |
  |  ③  FIN  “我也说完了,挂吧”    |
  | <--------------------------- |
  |                              |
  |  ④  ACK  “好,挂了”           |
  | ---------------------------> |
  |                              |
  |          连接关闭            |
​

一步步拆:

  • 第一次:客户端发 FIN,“我这边没数据要发了,想关”
  • 第二次:服务端回 ACK,“知道了”
  • 第三次:服务端发 FIN,“我这边也说完了,可以关了”
  • 第四次:客户端回 ACK,“好,那就关”

重点 为啥关闭要多一次

这才是最开始那个卡住我的问题。同样是确认,凭啥握手三次、挥手四次?

差别就在中间那两步能不能合并。

先看握手。第二次的 SYN+ACK 里,ACK 和 SYN 是一起发的——服务端刚收到请求,它既能立刻确认“我收到了”(ACK),又能顺势说“我也想跟你建连”(SYN)。两件事没冲突,一步就干完了。所以握手是 3 次。

再看挥手。客户端发 FIN 说“我说完了”,服务端能马上回 ACK 说“知道了”,但它不能马上跟着说“那我也关”。

为啥?因为客户端说“我发完了”,不代表服务端也发完了。服务端手里可能还有没传完的数据要发给客户端。

所以服务端得先回个 ACK 稳住对方(“知道你要关了,但我这边还没完,你等等”),等自己的数据全都发完了,才能再发一个 FIN 说“现在我也说完了,挂吧”。

这就是关键:挥手时,ACK 和 FIN 没法像握手那样合并成一步,中间隔着“服务端把剩余数据发完”这段时间。

一句话总结这个经典问题:

  • 握手:确认收到(ACK)和请求建连(SYN)能合并发,所以 3 次
  • 挥手:确认收到(ACK)和请求关闭(FIN)中间隔着数据没发完,只能拆开发,所以 4 次

本质是因为连接是全双工的,两个方向要各自独立地关。客户端说完了,服务端不一定说完了,得分别喊停,自然就多出一步。

小结

TCP 这套东西,抓住两个核心就不用死记了。

  • 建连要确认双向都通:我发你能收、你发我能收,凑齐这四件事的最小握手次数就是 3
  • 断连要两个方向各自关:连接是全双工的,一方说完不等于另一方说完,得分别 FIN 一次

至于那个经典问题——为啥连接三次、关闭四次——记住这句就够:握手时那个“确认 + 建连”能合并成一步,挥手时那个“确认 + 关闭”中间夹着没发完的数据,只能拆成两步。多出来的那一次,就是这么来的。

下次再被问到,就不用光背流程了,把道理讲出来才叫真懂。那就自己拿张纸画一遍试试吧。

更多推荐

章节目录