硬核拆解 TCP 的三次握手与四次挥手

硬核拆解 TCP 的三次握手与四次挥手

掌握 TCP 协议是网络故障排查与技术面试中的核心能力。TCP(Transmission Control Protocol,传输控制协议)位于 OSI 七层模型的第四层——传输层。其核心任务是在不可靠的 IP 网络层之上,构建一个可靠的面向连接的字节流传输通道。

本文将深入拆解 TCP 的报文结构,并详细解析连接建立(三次握手)与连接断开(四次挥手)的底层逻辑与设计原理。

TCP 报文头部核心字段

要理解 TCP 协议,首先需了解其数据包结构。一个 TCP 报文段由头部数据两部分组成,头部通常为 20 字节,包含控制 TCP 工作的关键信息。以下是五个核心字段:

TCP Header Structure

  1. 源端口与目的端口(Source/Destination Port)

    • 各占 2 字节。
    • IP 地址解决“数据发给哪台主机”的问题,而端口号解决“数据发给主机上的哪个进程”的问题。
  2. 序列号(Sequence Number, seq)

    • 占 4 字节。
    • TCP 将数据视为无结构的字节流,每个字节都有编号。序列号指本报文段所发送数据的第一个字节的序号。
    • 作用:解决网络包乱序问题,确保数据按序重组。
  3. 确认号(Acknowledgement Number, ack)

    • 占 4 字节。
    • 表示期望收到对方下一个报文段的第一个数据字节的序号。
    • 若确认号为 $N$,代表前 $N-1$ 个字节均已正确接收,下一次期望收到序列号为 $N$ 的数据。
    • 作用:实现可靠传输的核心机制。
  4. 标志位(Flags)

    • 包含多个比特位,其中关键标志位如下:
      • SYN:用于建立连接。
      • ACK:表示确认号字段有效,接收方需关注。
      • FIN:用于关闭连接。
      • RST:用于重置异常连接。
  5. 窗口大小(Window Size)

    • 告知对方接收缓冲区还能容纳多少字节的数据。
    • 作用:实现流量控制的基础。

三次握手:建立可靠连接

三次握手的本质并非简单的“打招呼”,而是通信双方交换并确认彼此的初始序列号,确保双方的发送与接收能力均正常。

握手过程详解

  1. 第一次握手:客户端发送 SYN

    • 客户端随机生成初始序列号 $X$,填入序列号字段,将 SYN 标志位置为 1。
    • 客户端进入 SYN_SENT 状态。
  2. 第二次握手:服务端发送 SYN + ACK

    • 服务端收到 SYN 后,随机生成自己的初始序列号 $Y$。
    • 构造报文:SYN=1,ACK=1。
    • 序列号填入 $Y$,确认号填入 $X+1$(意为:我已收到你的 $X$,期待你发送 $X+1$)。
    • 服务端进入 SYN_RCVD 状态。
  3. 第三次握手:客户端发送 ACK

    • 客户端收到服务端的响应,检查确认号是否为 $X+1$。
    • 无误后,发送确认报文:ACK=1,序列号为 $X+1$,确认号为 $Y+1$(意为:我已收到你的 $Y$,期待你发送 $Y+1$)。
    • 至此,连接进入 ESTABLISHED 状态,握手完成。

Three-Way Handshake

为什么必须是三次?

  • 双向验证:三次握手确保了双方的发送能力和接收能力都经过了双向验证,且初始序列号均得到确认。
  • 两次握手的缺陷:若仅两次握手(客户端发 SYN,服务端回 SYN+ACK),客户端虽确认了自己能发能收,但服务端无法确认客户端是否收到了自己的 SYN+ACK。服务端无法确定客户端是否具备接收能力,可能导致资源浪费或连接状态不一致。
  • 四次多余:三次已足以让双方状态达成一致,增加次数只会浪费网络资源。

四次挥手:断开连接

TCP 是全双工协议,客户端关闭发送通道并不代表服务端也要立即关闭。服务端可能仍有数据需发送给客户端,因此断开连接需要四次交互。

挥手过程详解

  1. 第一次挥手:客户端发送 FIN

    • 客户端发送 FIN 报文,序列号为 $U$,进入 FIN_WAIT_1 状态。
    • 含义:客户端无数据可发,申请关闭发送通道。
  2. 第二次挥手:服务端回复 ACK

    • 服务端回复 ACK 报文,确认号为 $U+1$,进入 CLOSE_WAIT 状态。
    • 注意:此时连接处于半关闭状态。客户端不能发数据,但能收数据;服务端仍可继续发送未发完的数据。
  3. 第三次挥手:服务端发送 FIN

    • 等服务端数据发送完毕,发送 FIN 报文,序列号为 $W$,进入 LAST_ACK 状态。
  4. 第四次挥手:客户端回复 ACK

    • 客户端回复 ACK 报文,确认号为 $W+1$,进入 TIME_WAIT 状态。
    • 服务端收到 ACK 后,彻底关闭连接。

Four-Way Wave-Off

硬核知识点:为何需要 TIME_WAIT 状态?

客户端在发送最后一个 ACK 后,不能立即关闭,必须等待 2 倍 MSL(Maximum Segment Lifetime,最大段生存期)的时间。原因如下:

  1. 确保服务端收到最后的 ACK

    • 客户端发送的第四次 ACK 可能在网络中丢失或损坏。
    • 若客户端立即释放资源,当服务端因未收到 ACK 而重传 FIN 时,客户端将无法响应,导致服务端无法正常关闭连接。
    • 等待 2MSL 可确保服务端收到 ACK,或让服务端的重传 FIN 超时后自行关闭。
  2. 防止旧连接的数据干扰新连接

    • 四次挥手完成后,网络中可能仍残留旧连接的数据包。
    • 若客户端立即释放资源并复用相同的四元组(源IP、源端口、目的IP、目的端口)建立新连接,残留的旧数据包可能被误认为是新连接的数据,导致不可预知的错误。
    • 等待 2MSL 可确保网络中所有旧连接的数据包均已消失,从而安全地复用端口。

TIMEWAIT Mechanism

总结

本文详细解析了 TCP 协议的核心机制:

  • 报文结构:通过序列号、确认号、标志位等字段实现可靠传输。
  • 三次握手:通过三次交互交换初始序列号,确保双方收发能力正常。
  • 四次挥手:因全双工特性,需分步关闭发送与接收通道,并通过 TIME_WAIT 状态保障连接彻底关闭及网络环境清洁。

掌握这些底层原理,将有助于你在面对网络故障排查及技术面试时游刃有余。后续我们将继续探讨 TCP 的可靠传输机制及流量拥塞控制。