滑动窗口大小取接收窗口(rwnd)与拥塞窗口(cwnd)的较小值,由接收方缓冲区和网络拥塞状况共同决定;需启用窗口缩放、合理设置缓冲区上限并配合BBR等先进拥塞算法以平衡吞吐与稳定性。

滑动窗口不是“越大越好”,也不是固定不变的数值,它直接决定单位时间内能发多少数据、是否卡在等 ACK 上——本质上,它把网络带宽和延迟“翻译”成了可操作的字节数。
滑动窗口大小由接收方和网络共同决定
发送方实际能发的数据量,取两个值中的较小者:
- 接收窗口(rwnd):由对方当前接收缓冲区剩余空间决定,通过 TCP 头部的 window 字段通告;
- 拥塞窗口(cwnd):由本端根据网络状况动态计算,受丢包、延迟变化影响,由拥塞控制算法(如 CUBIC 或 BBR)驱动。
真正起作用的发送窗口 = min(rwnd, cwnd)。如果对方应用层读得慢,rwnd 就会缩小,哪怕网络很空闲,你也只能慢慢发;反过来,即使 rwnd 很大,但路径上出现丢包,cwnd 就会被压低,窗口自动收窄。
窗口太小,速度被“憋死”
TCP 报文头中原始 window 字段只有 16 位,理论最大 65535 字节。在现代网络中这远远不够:
- 例如:100 Mbps 带宽 + 50 ms RTT → 带宽时延积(BDP)≈ 625 KB;
- 若窗口卡在 64 KB,链路利用率不足 10%,大量带宽闲置;
- 这时必须启用 tcp_window_scaling=1,让窗口通过缩放因子扩展到 GB 级别。
否则,再快的网卡、再大的接收缓冲区,TCP 层也“看不见”,照样跑不满速。
窗口太大,反而引发丢包和重传
窗口不是无上限放大就行。当发送窗口持续大于路径实际 BDP 时:
- 中间路由器队列溢出,开始主动丢包;
- 丢包触发拥塞控制,cwnd 急剧下降,传输速率断崖式回落;
- 频繁重传进一步加剧链路压力,形成恶性循环。
所以内核默认不会盲目拉满缓冲区,而是配合自动调优机制(如 net.ipv4.tcp_rmem 和 net.ipv4.tcp_wmem 的第二、三参数)按需伸缩,兼顾吞吐与稳定性。
调整窗口相关参数的关键点
真正影响速度的不是单个参数,而是它们之间的协同:
- 确保 tcp_window_scaling=1 已开启(默认通常已开),否则窗口无法突破 64 KB;
- 接收缓冲区上限(tcp_rmem[2])应 ≥ 预期 BDP,例如千兆局域网(RTT ≈ 0.2 ms)需设为 2 MB 以上;
- 发送缓冲区(tcp_wmem)不宜设得过大,避免掩盖真实拥塞信号;
- 启用 BBR 拥塞算法(net.core.default_qdisc=fq + net.ipv4.tcp_congestion_control=bbr)可更精准适配窗口,尤其对高延迟链路效果明显。


















