Skip to content

为什么是三次握手、四次挥手? ​

三次握手是为了双方确认对方能收到自己的报文,并同步起始序号。两次不够:服务器还不知道自己的响应有没有到达客户端。四次挥手是因为 TCP 是全双工,每一端都要单独关掉自己的发送方向。

原理 ​

握手:

  1. 客户端发 SYN,带上自己的初始序号。
  2. 服务器回 SYN+ACK,确认客户端的序号,并带上自己的初始序号。
  3. 客户端发 ACK,确认服务器的序号。

这三次之后,双方都知道连接可用。初始序号不能从 0 固定递增,否则旧连接的延迟报文可能被新连接接受。

挥手:

  1. 主动关闭方发 FIN。
  2. 对方 ACK。这时对方可能还有数据要发,连接处于半关闭。
  3. 对方发完后也发 FIN。
  4. 主动方 ACK,再等一段时间才真正释放,用来消化迟到的报文。

第三次握手的 ACK 可以携带数据,所以建立连接的往返通常是一次。挥手的最后等待是 TIME_WAIT,主动关闭方会短时间占着这个端口对。

追问 ​

TIME_WAIT 过多会怎样?

主动关闭的一端堆积 TIME_WAIT,新连接可能暂时用不上同一对地址。服务端应让客户端主动关闭,或复用连接(keep-alive、HTTP/2),而不是每个请求都新建再立刻关。

和 TLS 握手是一回事吗?

不是。TCP 握手之后,HTTPS 还要做 TLS 握手。见 HTTPS。

易错点 ​

  • 把四次挥手说成「必须连续四个包、中间不能带数据」。半关闭期间对端仍可发送剩余数据。
  • 两次握手就被认为可以传数据。服务器发出的 SYN 还没被确认。
  • 挥手次数说成三次。特殊实现可能把 ACK 和 FIN 合并,但模型上每一端都要确认对方的关闭。

相关 ​