从 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 是全双工连接,一方不发了,不代表另一方也发完了

常见问题

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

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

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

TCP 一定比 UDP 好吗

不一定。

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

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

总结

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

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

Reference