TCP窗口大小

TCP 头部包含一个 16 位(Bit)的 Window Size 字段。
Window Scale(窗口扩大因子,WSopt) 是一个仅在建立连接时使用的协商选项(RFC 1323/RFC 7323):

  1. 只出现于握手阶段:它只能出现在带 SYN 标志位的报文里(即客户端的 SYN 和服务端的 SYN-ACK)。

  2. 协商即固定:双方在 SYN 包中告知对方自己的移位因子(Shift Count)。一旦三次握手完成,连接存续期间移位因子就不再更改,后续的 ACK 或数据包中不会再包含 Window Scale 选项。

  3. 双向独立:客户端和服务端协商的 Shift Count 可以不同(比如客户端指定 7,服务端指定 8)。如果其中一方在 SYN 中没有带 Window Scale 选项,双方在后续通信中都不能使用窗口扩大功能。

  4. 计算应用于后续所有包:握手完成后,后续所有数据包和 ACK 包 TCP 首部里的 16 位 Window Value,都会自动乘以握手时确定的 2^{\text{Shift Count}}。

在 TCP 三次握手的第一步(第一个 SYN 包),发送方(Client)在还没有收到任何数据的情况下,就已经在 TCP 首部的 Window Size 字段填入了一个数值(例如 64240)。

  • 含义:这是客户端在告诉服务端:“如果握手成功,我(作为接收方)初始建立的接收缓冲区大小是这么多,你可以按这个规格发数据给我。”

  • 双方对称:随后服务端回复的 SYN-ACK 包中,也会带上服务端自己的初始 Window Size。

  • 接收方发送 ACK 时,会同时附带最新的窗口大小(通告窗口,Advertised Window)。

  • 当接收方缓冲区满了,它会发送 Window Size = 0(零窗口,Zero Window),此时发送方必须暂停发送数据,直到收到接收方发送的窗口更新(Window Update)
    发送方实际能发送的数据量不仅受接收方限制,还受网络拥塞程度影响:

    \text{Effective Window} = \min(\text{rwnd}, \text{cwnd})
  • rwnd (Receiver Window):接收方通告窗口,反映接收端能力。

  • cwnd (Congestion Window):拥塞窗口,由发送方根据网络拥塞算法(如 Reno、CUBIC、BBR)计算得出,反映网络传输能力。

1. TCP 窗口扩大因子 (Window Scale Option)

TCP 报文首部原本只保留了 16 位来表示窗口大小,因此原始最大窗口为:

2^{16} - 1 = 65,535 \text{ 字节 (约 64 KB)}

在高带宽延时积网络(BDP,Bandwidth-Delay Product,如千兆光纤、跨国长途网络)中,64 KB 的窗口会成为严重限制网络吞吐量的瓶颈。

为了解决这个问题,RFC 1323 引入了 TCP Window Scale Option(WSopt):

  • 发生在 TCP 三次握手阶段(SYN 报文中协商)。

  • 增加一个位移因子(Shift Count,范围 0~14)。

  • 实际窗口大小计算公式为:

\text{Actual Window Size} = \text{TCP Header Window Value} \times 2^{\text{shift\_count}}
  • 最大理论窗口:当位移因子为 14 时,最大窗口可扩展至 65,535 \times 2^{14} \approx 1 \text{ GB}。
    image.png

评论