从 TCP 要解决的问题出发,理解三次握手、四次挥手、可靠传输和 TIME_WAIT。

2026-03-02 11:12:31
之前只是举了个打电话的例子, 让 ai 补充了一下。 真记不住..

TCP 是传输层协议,核心目标是:在不可靠的网络之上,尽量提供可靠、有序、面向连接的数据传输。

它比 UDP 多做了很多事情,比如建立连接、确认数据、超时重传、流量控制、拥塞控制。三次握手和四次挥手,就是 TCP 管理连接生命周期的两个关键过程。

TCP 解决什么问题

网络本身并不保证数据一定能到达。数据包可能丢失、乱序、重复,也可能因为网络拥塞而延迟。

TCP 主要通过这些机制提高可靠性:

  • 序列号:给每段数据编号,用来判断顺序和去重
  • 确认应答:接收方收到数据后返回 ACK,告诉发送方已经收到
  • 超时重传:发送方长时间收不到 ACK,会重新发送数据
  • 流量控制:接收方告诉发送方自己还能接收多少数据,避免被打爆
  • 拥塞控制:根据网络情况调整发送速度,避免把网络打满

所以 TCP 不是“绝对可靠”,而是在 IP 这种尽力而为的网络之上,提供一套可靠传输机制。

三次握手

三次握手的目的不是单纯“打个招呼”,而是确认双方都具备发送和接收能力,并同步初始序列号。

可以先用类比理解:

  1. 客户端:我能发消息,你能收到吗?
  2. 服务端:我收到了。你也能收到我发的消息吗?
  3. 客户端:我收到了,我们开始通信吧。

对应到 TCP 报文,大致是:

客户端 -> 服务端: SYN, seq = x
服务端 -> 客户端: SYN + ACK, seq = y, ack = x + 1
客户端 -> 服务端: ACK, ack = y + 1

第一次握手

客户端发送 SYN 报文,表示希望建立连接,并带上自己的初始序列号 seq = x

此时客户端进入 SYN_SENT 状态。

第二次握手

服务端收到 SYN 后,返回 SYN + ACK

  • ACK 表示已经收到客户端的 SYN
  • ack = x + 1 表示期望客户端下次从 x + 1 开始发送
  • SYN 表示服务端也要同步自己的初始序列号 seq = y

此时服务端进入 SYN_RECEIVED 状态。

第三次握手

客户端收到服务端的 SYN + ACK 后,再发送一个 ACK,确认自己收到了服务端的初始序列号。

这一步完成后,客户端和服务端都进入 ESTABLISHED 状态,连接建立完成。

为什么是三次握手

两次握手只能证明:

  • 服务端能收到客户端的数据
  • 客户端能收到服务端的数据

但服务端还不能确认:客户端是否真的收到了自己的 SYN + ACK

第三次握手的价值就在这里:让服务端确认客户端的接收能力正常,同时避免历史连接请求因为网络延迟突然到达,导致服务端误建连接。

一句话总结:

三次握手是为了确认双方的发送和接收能力都正常,并同步双方的初始序列号。

四次挥手

TCP 是全双工通信。也就是说,客户端和服务端两边都可以同时发送数据。

关闭连接时,不能简单地一方说“我不发了”,另一方就立刻断开。因为一方停止发送数据,不代表另一方的数据也已经发完。

可以先用类比理解:

  1. 客户端:我这边数据发完了,准备关闭。
  2. 服务端:我知道了,但我可能还有数据没发完。
  3. 服务端:我这边也发完了,可以关闭。
  4. 客户端:收到,那连接关闭。

对应到 TCP 报文,大致是:

客户端 -> 服务端: FIN
服务端 -> 客户端: ACK
服务端 -> 客户端: FIN
客户端 -> 服务端: ACK

第一次挥手

主动关闭方发送 FIN,表示自己已经没有数据要发送了。

注意:发送 FIN 只代表这一侧不再发送数据,但仍然可以接收对方的数据。

第二次挥手

被动关闭方收到 FIN 后,先返回 ACK,表示已经知道对方要关闭发送方向。

此时被动关闭方可能还有数据没发送完,所以不能立刻发送 FIN

第三次挥手

被动关闭方把剩余数据发送完后,再发送 FIN,表示自己也没有数据要发送了。

第四次挥手

主动关闭方收到 FIN 后,返回 ACK。被动关闭方收到这个 ACK 后关闭连接。

主动关闭方不会马上消失,而是进入 TIME_WAIT 状态,等待一段时间后才真正关闭。

为什么需要 TIME_WAIT

TIME_WAIT 主要有两个作用:

  • 确保最后一个 ACK 能到达对方:如果最后的 ACK 丢了,对方会重发 FIN,主动关闭方还可以再回 ACK
  • 避免旧连接的数据影响新连接:等待网络中旧连接的报文自然过期,防止它们混入后续新连接

所以 TIME_WAIT 不是无意义的等待,而是 TCP 为了可靠关闭连接付出的成本。

三次握手和四次挥手的区别

过程目的为什么是这个次数
三次握手建立连接,确认双方收发能力,同步初始序列号第三次握手让服务端确认客户端能收到自己的响应
四次挥手关闭连接,分别关闭两个方向的数据传输TCP 是全双工连接,一方不发了,不代表另一方也发完了

常见问题

为什么建立连接是三次,关闭连接是四次

建立连接时,服务端可以把 SYNACK 合并在同一个报文中返回,所以是三次。

关闭连接时,收到 FIN 的一方通常还可能有数据没发送完,只能先回 ACK,等数据发送完后再单独发送 FIN,所以通常是四次。

TCP 一定比 UDP 好吗

不一定。

TCP 适合需要可靠、有序传输的场景,比如网页、接口请求、文件传输。UDP 更适合低延迟、允许少量丢包的场景,比如直播、语音、游戏、DNS 查询。

选择 TCP 还是 UDP,不是看哪个“更高级”,而是看业务更需要可靠性还是实时性。

总结

TCP 的重点不是背诵“三次握手、四次挥手”,而是理解它们分别在解决什么问题:

  • 三次握手:确认双方收发能力正常,并同步初始序列号
  • 四次挥手:分别关闭两个方向的数据传输
  • TIME_WAIT:保证连接可靠关闭,并避免旧报文影响新连接
  • 可靠传输:依赖序列号、ACK、重传、流量控制和拥塞控制共同完成

Reference