tcpdump过滤ack包需用bpf表达式tcp[tcpflags] & (tcp-ack) != 0,通过字节偏移和位运算匹配tcp标志位;可进一步限定纯ack、ack+syn等组合或端口、方向等条件。

直接用 tcpdump 过滤带 ACK 标志的 TCP 包,关键在于使用 BPF 表达式匹配 TCP 头部的标志位。ACK 是 TCP 控制标志(TCP Flags)之一,不能靠协议名或端口判断,必须通过字节偏移和位运算提取。
基础命令:抓取所有含 ACK 的 TCP 包
执行以下命令即可捕获所有携带 ACK 标志的 TCP 数据包:
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-ack) != 0' -nn
说明:tcp[tcpflags] 表示读取 TCP 头部中标志位所在的字节(通常为第 13 字节,从 0 开始计数);(tcp-ack) 是 tcpdump 内置常量,对应 ACK 位(二进制 00010000,即十进制 16);& 是按位与操作,结果非零说明 ACK 位被置起。
按方向或组合条件进一步过滤
单独 ACK 包(如纯确认、无数据)或与其他标志共存(如 ACK+SYN、ACK+FIN、ACK+RST)都属于“带 ACK”,可根据需要加限定:
- 只抓纯 ACK(无 SYN/FIN/RST/PSH/URG):
'tcp[tcpflags] == tcp-ack' - 抓 ACK+SYN(即服务端对 SYN 的响应):
'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)' - 抓 ACK+FIN(四次挥手第二步):
'tcp[tcpflags] & (tcp-fin|tcp-ack) == (tcp-fin|tcp-ack)' - 限制到某端口(如目标端口 80):
and dst port 80 - 只看本机发出的 ACK:
src host $(hostname -I | awk '{print $1}')
注意区分:ACK 是 TCP 层标志,不是所有协议都有
该过滤仅适用于 TCP 协议。UDP、ICMP、ARP 等不使用 ACK 标志:
- 加
tcp前缀可确保只匹配 TCP 流量:tcp and tcp[tcpflags] & (tcp-ack) != 0 - 若误写成
ip[tcpflags]或漏写tcp,表达式会出错或匹配失败 - UDP 包里没有 ACK 位,用同样表达式不会命中,无需额外排除
辅助验证与常见用途
抓到 ACK 包后,常用于分析连接状态是否正常、确认是否及时到达、是否存在延迟确认(Delayed ACK)等:
- 观察时间戳和序列号变化,判断是否为重复 ACK(dup ACK),提示丢包
- 结合
-tttt查看绝对时间,配合前后报文分析 ACK 间隔 - 保存为 pcap 文件供 Wireshark 深度查看:
-w ack.pcap - 快速统计 ACK 数量:
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-ack)' -c 100 | wc -l











