轻松理解 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 一次
至于那个经典问题——为啥连接三次、关闭四次——记住这句就够:握手时那个“确认 + 建连”能合并成一步,挥手时那个“确认 + 关闭”中间夹着没发完的数据,只能拆成两步。多出来的那一次,就是这么来的。
下次再被问到,就不用光背流程了,把道理讲出来才叫真懂。那就自己拿张纸画一遍试试吧。
