确认内核是否发出零窗口通告,需用tcpdump抓取Window字段为0的ACK包:tcpdump -i any 'tcp[tcpflags] & tcp-ack != 0 and tcp[14:2] == 0',该命令读取原始TCP头第14–15字节(缩放前值),比Wireshark解码后的window_size更可靠;ss -i中rcv_space≤0或极低、rcv_ssthresh骤降可间接佐证,而dmesg和/proc/net/snmp默认不记录zero window事件。

怎么确认内核是否发出零窗口通告(zero window)
Linux 内核本身不会“主动报错”或打日志说“我发了 zero window”,它只是在 ACK 报文中把 Window 字段设为 0。所以所谓“查看内核报出的 zero window”,本质是抓到那个 Window: 0 的 ACK 包,并确认它是内核协议栈发出的(而非应用层伪造或中间设备干扰)。
- 用
tcpdump过滤真实 zero window 通告:tcpdump -i any 'tcp[tcpflags] & tcp-ack != 0 and tcp[14:2] == 0'—— 这条命令直接读取 TCP 头部第 14–15 字节(即 Window 字段),匹配值为 0 的 ACK 包 - 注意:不要用
tcp.window_size == 0,Wireshark 显示的 window_size 是经窗口缩放因子(WScale)解码后的值,而内核原始通告仍是缩放前的整数;tcpdump原生语法读的是原始字段,更可靠 - 如果看到连续多个
Window: 0的 ACK,且紧随其后出现小序号重复 ACK(如 seq=100, ack=200;下一条还是 seq=100, ack=200),基本可判定是零窗口探测(zero window probe)已启动
ss -i 能不能看出接收窗口为 0
ss -i 不会直接显示 “rwnd=0”,但它能提供关键线索:看 rcv_space 和 rcv_ssthresh 是否接近 0,再结合 rtt 和 cwnd 判断是否被限速。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
-
rcv_space是内核当前为该 socket 分配的接收缓冲区剩余空间(字节),若长期 ≤ 64KB 且rtt突增、cwnd锁死在 1 MSS,大概率接收方已无法消费数据 -
rcv_ssthresh若降到极低(如 536),说明内核已触发零窗口恢复逻辑,正在试探性发送 probe - 运行
ss -ti dst <code>IP:PORT可聚焦单连接;若rcv_space为 0 或负数(某些内核版本显示为 0),基本坐实接收窗口耗尽
为什么 dmesg / /proc/net/snmp 里找不到 zero window 日志
因为 zero window 是 TCP 协议的正常流控行为,不是错误,内核默认不记录。你不会在 dmesg 或 /proc/net/snmp 中看到 “TCP zero window” 这类字样 —— 它不像 SynsToListenDrops 或 TcpRcvQDrop 那样有专用计数器。
-
TcpRcvQDrop(/proc/net/snmp第 19 列)只统计因接收缓冲区满而丢弃的数据段,和 zero window 通告无直接关系;它涨了说明应用 read 太慢,但 zero window 可能早已发生多次 - 真正能间接佐证的,是
ss -s输出里的orphan数量:若orphan持续 >tcp_max_orphans,内核可能强制回收连接并发送 RST,此时才会在dmesg打印"TCP: too many orphaned sockets" - 换句话说:zero window 本身静默,但它的后果(如 probe 超时、连接僵死、orphan 积压)才可能留下可观测痕迹
容易忽略的关键点:窗口缩放(Window Scale)的影响
现代 Linux 默认启用窗口缩放,Window 字段实际是缩放后的值。如果你在抓包里看到 Window: 0,那确实是 0;但如果看到 Window: 14600,不代表真实窗口就是 14600 —— 它可能是 14600 (缩放因子为 7)。
- 确认缩放因子:抓包看 SYN 包的
wscale选项,或查ss -i输出中的wscale字段(如wscale:7,7表示收/发各缩放 7 位) - 误判常见于:看到
Window: 65535就以为窗口已拉满,其实可能是缩放后上限(65535 - 因此,判断是否真“满”,必须结合
rcv_space(内核视角的剩余字节数)和Window字段原始值,二者都要为 0 才算真正 zero window


















