1693 字
8 分钟
浅谈 TCP 窗口优化
2025-10-02

TCP 窗口优化#

不论宽带速度(例 500Mbps 或 1000Mbps),连接到一些海外服务器或物理距离遥远的数据中心或机房时,下载或传输速度有时特别的慢,与测试结果不符,
很大程度上是高网络延迟(RTT)与 TCP 协议的固有设计共同作用的结果。

1. 高延迟下的 TCP 吞吐量陷阱#

所有基于 TCP 的网络传输(如网页浏览、文件下载、VPN 连接等)都依赖于一个叫作 TCP 窗口的机制。窗口的作用是限制发送方在收到接收方确认之前可以发送的数据量。

为什么高延迟是性能杀手?#

根据 TCP 的设计,数据吞吐量受到以下公式的严格限制:

吞吐量窗口大小/往返时间(RTT)吞吐量 ≤ 窗口大小 / 往返时间 (RTT)

在跨越国家或大洲的长距离连接中,RTT 动辄超过 150 毫秒。而原始的 TCP 窗口大小只有 65535 字节(64 KiB - 1)。这意味着我们的发送方在发出少量数据后,必须等待漫长的时间(一个 RTT 周期)才能得到确认并发送下一批数据,导致带宽大量闲置。

长距离连接对窗口的需求:带宽时延积 (BDP)#

为了完全跑满我们的带宽,TCP 窗口的大小必须能覆盖网络管道的实际容量,这被称为带宽时延积 (BDP):

BDP=带宽×RTTBDP = 带宽 × RTT

实际计算示例:假设我们的宽带是 1 Gbps,而连接到北美西海岸服务器的 RTT 是 150 毫秒 (0.15 秒):

  • 原始窗口(65535 字节)的最大理论吞吐量仅约为 3.49 Mbit/秒。
  • 根据 BDP 计算,我们需要的最优 TCP 窗口大小约为 18.75 MB。只有当窗口能扩展到 18.75 MB 时,我们才有机会跑满 1 Gbps 的带宽。

2. Windows 的解法:窗口自动调优#

好消息是,微软早就意识到了这个问题。自 Windows Vista 以来,Windows 系统默认启用了一项名为 “TCP 自动调优接收窗口”(Receive Window Auto-Tuning) 的功能。

自动调优的作用#

  • 启用窗口缩放:它利用 TCP 窗口缩放扩展(Window Scaling),打破了 64KB 的原始限制,允许窗口大小动态扩展到数 MB 甚至更高(最高可达 1 GiB)。
  • 动态匹配 BDP:Windows 系统会持续监测当前的网络 RTT 和应用程序的数据处理速度,智能地将 TCP 窗口大小调整到尽可能接近 BDP 的最优值。(当然是理论上)

如何检查自动调优状态?#

我们可以通过 PowerShell 或 CMD 运行以下命令,查看我们的 TCP 全局参数。请关注 “Receive Window Auto-Tuning Level” 的值。

Terminal window
# 在 Windows 10/11 的 PowerShell 或 CMD 中执行
netsh interface tcp show global

如果其值为 normal,则表示自动调优已开启并处于正常工作状态。如果是 disabled,执行下面的命令。

Terminal window
# 启用自动调优(仅在确认被禁用时使用)
netsh interface tcp set global autotuninglevel=normal

3. RFC 1323 TCP 扩展#

RFC 1323(TCP Extensions for High Performance)是 TCP 的经典标准。定义了三个关键扩展,让 TCP 在高带宽、高时延(高 BDP)的情况保持一定的性能。

窗口缩放(Window Scaling):#

原始 TCP 的窗口字段只有 16 位,最多 65535 字节,在高 BDP 场景下(如 1Gbps 带宽 + 150ms RTT)根本不够用——窗口太小,数据流动缓慢。RFC 1323 引入窗口缩放选项,将窗口定义扩展到 32 位(约 4GB),通过一个缩放因子(scale factor,0-14,对应 2^0 到 2^14 倍)在 SYN 包中协商。

  • 协商机制:连接建立时(SYN 段),发送方在 TCP 选项中声明 Window Scale(WSOPT,Kind=3,Length=3,Shift.cnt=缩放值)。接收方如果支持,也在 SYN-ACK 中回应相同的选项。
  • 性能益处:拿我们上面的示例来说(BDP=18.75MB),如果 Shift.cnt=14(16384 倍),16 位字段只需 1146(18.75MB / 16384)就可以覆盖整个Tunnel,避免带宽闲置。

Tips:用 Wireshark 抓包查看 SYN 包的选项字段是否有 WSOPT ,确认缩放是否生效。

TCP 时间戳(Timestamps):#

高延迟网络下,RTT 估算不准会导致拥塞控制失灵,窗口调整迟钝。RFC 1323 的时间戳选项(TSOPT,Kind=8)在每个段中嵌入 32 位时间戳(TSval)和回显值(TSecr),用于两个目的:

  • RTT 测量(RTTM):接收方回显发送方的 TSval,发送方计算精确 RTT(不受重传干扰),优化窗口增长和重传超时。
  • 序列号包装保护(PAWS):在高吞吐量的情况下,32 位序列号容易wrap around,通过时间戳检查,过时的包会被丢弃,保证序列正常。

Tips:时间戳虽然增加了 12 字节的开销,但感觉是利大于弊 —— Red Hat 等系统默认启用,能更好地估算 RTT , Windows 也默认支持。

时间戳可能泄露系统时钟,但 RFC 建议随机偏移来防止时序攻击,要自己考量

路径 MTU 发现(Path MTU Discovery)#

虽然不是 RFC 1323 核心,但1323更新了 RFC 1191 的 PMTUD,支持了 DF(Don’t Fragment)位和 ICMP 反馈,动态寻找链路里最大的传输单元(MTU)。这防止了分片开销,在高延迟链路中减少重传的次数。当我们用 VPN , MTU 也不会乱序匹配,这确保了包大小自适应,避免“黑洞”路由出现。

RFC 1323 已于 2015 年被 RFC 7323 更新(obsoleted),但核心机制不变。 在 Windows 上,通过 netsh 命令来调整(比如打开 PMTUD)

4. 还有什么要说的……#

常见瓶颈排查#

  • 路由器/ISP 限制:检查是否启用了 QoS 限制,或 ISP 的国际出口堵塞。可以用 tracert google.com 看看高延迟的节点。
  • DNS:测一下延迟,建议用低延迟的非运营商 DNS 。
  • 连接方式:优先用有线连接,减少 Wi-Fi 信号弱导致的衰减。
  • MTU:默认 MTU 1500 适合大多数场景,但如果连续使用 VPN,可以试试修改:netsh interface ipv4 set subinterface "以太网" mtu=1400 store=persistent
  • 你在哪里:地区的不同导致出口延迟不同,建议肉身横渡。

额外优化#

  • 启用 CTCP(复合 TCP):增强拥塞控制:netsh interface tcp set global congestionprovider=ctcp。在高带宽高延迟场景下更高效。
  • 禁用 Nagle 算法(游戏/Live):netsh interface tcp set global nagle=disabled。但这会增加小包开销,不适合文件传输,其实不太推荐。
  • VPN 优化:如果经常用 VPN,选择 WireGuard 协议,会自动处理窗口缩放。
  • 禁用代理(ProxyEnable):如果用不着代理服务器,那开启代理可能会增加额外延迟。通过注册表编辑器(regedit)导航到 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings,将 ProxyEnable 的值设置为 0(DWORD 类型)。

参考
ietf.org
knowledge.broadcom.com
cisco.com
learn.microsoft.com rfc-editor.org

浅谈 TCP 窗口优化
https://blog.chuwu.top/posts/2025-10-02/tcp-window-optimization/
作者
ChuwuYo
发布于
2025-10-02
许可协议
CC BY-NC-SA 4.0