---
date: 2026-10-26 23:32
created: 2026-10-26 23:32
updated: 2026-10-26 23:32
categories:
tags:
---
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](https://shinerio.oss-cn-beijing.aliyuncs.com/obsidian202610262336943.png)
