排查网络问题这么多年,我踩过最多的坑不是"找不到问题",而是"根本没抓到该抓的包"。很多人第一次打开 Wireshark,对着满屏滚动的高亮颜色一脸懵,抓了十分钟发现网卡选错了、过滤器写错了、或者抓到一半软件卡死了。这篇就按我自己实际的排查流程走一遍,从安装那一刻开始讲,重点放在抓包之前该想清楚什么、抓完之后怎么把几万个包筛成有用的那几个,以及那些教程里从来不写、但实际会把人卡住半天的细节。不管你是刚接触网络协议的新手,还是被某个偶发卡顿折磨了很久、想拿抓包工具定位问题的开发者,下面这些内容都能直接照着复现。
1. 装对 Wireshark:后面八成的折腾都出在这一步
1.1 Npcap 和 WinPcap 的选择,决定了你能抓到什么
Windows 上安装 Wireshark 时,安装程序会问你装不装 Npcap。这个东西是抓包能力的底座,它负责把网卡收到的原始数据交给 Wireshark。老教程里经常出现的 WinPcap 早就不更新了,在 Windows 10、Windows 11 上装老版本 WinPcap 会有一堆兼容问题,比如网卡列表里看不到无线网卡、抓到一半驱动崩掉。所以现在装包时直接用安装向导自带的 Npcap 就行,勾选"Install Npcap"那一步别跳过。
Npcap 安装界面里有一个容易忽略的选项,就是"Support raw 802.11 traffic"。如果你打算分析 Wi-Fi 的空口流量,比如研究 802.1x 认证过程,这个选项要勾上;如果你只是抓有线网口或者本机的普通流量,勾不勾影响不大。还有"Restrict Npcap driver's access to Administrators only",个人开发机建议不要勾,否则每次开 Wireshark 都要处理权限提升,很烦。
装完重启一下,打开 Wireshark 看接口列表能不能正常显示。如果只有一两个奇怪的接口、看不到你实际的网卡,多半是 Npcap 没装好或者被安全软件拦了,重装一遍 Npcap 通常能解决。
1.2 第一次启动就该改掉的几个默认设置
第一次打开 Wireshark,别急着点那个鲨鱼鳍图标开始抓。先做几件让后面省心的事。
第一,把时间列的显示格式改掉。默认显示的是"从抓包开始到现在"的绝对秒数,排查问题时不好用。进"视图 - 时间显示格式",改成"自上一显示包的时间",单位选秒。这样每一行显示的就是这个包和上一个包之间的间隔,找卡顿、找超时的包特别直观。
第二,关闭"实时滚动"或者至少心里有数。抓包时列表一直在滚,你想点某个包很容易点错。可以先把滚动关掉,或者抓到关键包后立刻用 Ctrl+E 停止抓包,再慢慢看。
第三,把"捕获"菜单里的"选项"打开看一眼。这里有个 snaplen(快照长度)设置,默认是 262144。这个值如果被改小了,你抓到的包就只有前面一小段数据,后面全是截断的。很多"为什么只能看到部分字节"的疑问,根子就在这里。
第四,弄懂一个概念:Wireshark 抓的是经过你网卡的所有流量,包括别人的广播、组播、各种协议的心跳包。所以第一件事永远是缩小范围,而不是打开就开始录。你录得越久、范围越大,后面筛起来越痛苦。
2. 抓包之前先想清楚:在哪抓、抓什么、抓多久
2.1 网卡选择、混杂模式和无线网卡的差异
打开 Wireshark,接口列表里会有一排网卡。选哪个,取决于你要看的是"本机进出流量"还是"整个网段的流量"。
如果你要看本机发出去和收进来的请求,选正在使用的那块网卡就行。如果是本机访问外部服务的问题,有线选以太网卡,无线选无线网卡。这里有个反直觉的点:抓本机自己访问自己的服务(比如 localhost 上的服务),很多情况下抓不到,因为这类流量走的是内核回环,不经过物理网卡。要抓回环流量得装专门的环回适配器,或者用 Npcap 自带的环回接口。
混杂模式是另一个常被误解的东西。勾选它之后,网卡会接收经过它的所有帧,而不只是发给自己的。但要注意,在现在这种交换式网络里,交换机默认只把帧转发到你所在的端口,所以你在自己电脑上开混杂模式,也只能看到广播、组播和发给自己的包,看不到别的机器的单播流量。想看整个网段的流量,得在交换机上做端口镜像,或者在上游设备上抓。这个认知很重要,否则你会一直奇怪"为什么我抓不到别人的流量"。
无线网卡的情况又不一样。普通无线网卡驱动默认只把连接到自己网络的数据交上来,要抓空口上的管理帧、认证帧,得让网卡进入监听模式。像 Intel AX210 这类网卡在特定驱动下支持监听模式,配合 Wireshark 就能看到 802.11 的管理报文,包括 802.1x 的 EAPOL 认证交互。不过能不能进监听模式,很大程度上看驱动和系统支持,不是所有无线网卡都行。
2.2 捕获过滤器和显示过滤器:性能差别不止一点点
这是我见过最多人搞混的地方。Wireshark 里有两套过滤器,作用位置完全不同。
捕获过滤器(Capture Filter)在"捕获选项"里填,用的是 BPF 语法,它在内核层就生效,不符合条件的包根本不会被记录下来。显示过滤器(Display Filter)在抓完之后的主界面顶部填,是 Wireshark 自己的语法,它只是把已经抓到的包筛着显示,包其实都还在。
为什么要分清?因为捕获过滤器能大幅减少记录量。你在一台流量很大的机器上抓包,不加捕获过滤,几秒钟就是几十万个包,内存飙升、软件卡顿。如果只是要看 80 端口的流量,直接在捕获过滤里写tcp port 80,抓到的就干净很多。
但捕获过滤器的语法比较"硬",写错了不报错,只是抓不到东西。所以我的习惯是:先用宽泛的捕获过滤缩小协议范围或地址范围,抓下来之后再用显示过滤器精细分析。两个阶段配合,既保证性能,又保证灵活。
常见的捕获过滤器和显示过滤器写法对照如下:
| 目的 | 捕获过滤器(BPF) | 显示过滤器 |
|---|---|---|
| 只看某台主机 | host 192.168.1.100 | ip.addr == 192.168.1.100 |
| 只看某端口 | port 443 | tcp.port == 443 |
| 只看 UDP | udp | udp |
| 只看某主机某端口 | host 192.168.1.100 and port 8080 | ip.addr == 192.168.1.100 && tcp.port == 8080 |
| 排除某主机 | not host 192.168.1.1 | !(ip.addr == 192.168.1.1) |
注意两套语法的连接符不一样:BPF 用and、or、not,显示过滤器用&&、||、!。混用会直接报红,这是新手最容易卡住的第一关。
3. 显示过滤器:把几万个包筛到只剩你要的那几个
3.1 基础语法和几个高频率表达式
抓到包之后,真正的活是筛选。显示过滤器输入框支持自动补全,输入的时候会提示可用字段,善用这个功能能少记很多语法。
最常用的几个表达式,我列一份直接能抄的:
ip.addr == 192.168.1.100:只看这个 IP 参与的所有包,不区分方向ip.src == 192.168.1.100:只看这个 IP 发出的包tcp.port == 8080:只看 8080 端口的 TCP 流量http.request:只看 HTTP 请求tcp.flags.syn == 1 && tcp.flags.ack == 0:只看 TCP 的第一次握手包tcp.analysis.retransmission:只看重传的包udp && ip.addr == 10.0.0.5:UDP 和地址两个条件组合
写过滤器的一个小技巧是善用contains和matches。比如你想找某个 HTTP 请求的 body 里出现了特定字符串,可以写http contains "login"。想按正则匹配某些内容,用matches。这些在排查具体业务问题时非常有用,比一个个点开看快得多。
3.2 算 UDP 前后两包时间间隔:改时间显示比写过滤器更直接
有人问过我怎么筛出 UDP 前后两包的时间间隔。严格说,Wireshark 没有一个"直接过滤出间隔"的字段,但有个更省事的办法。
先把过滤器设成udp,把显示过滤后的时间列改成"自上一显示包的时间"(前面第 1.2 节讲过怎么改)。这样列表里每一行显示的,就是当前包和上一个被显示的 UDP 包之间的时间差。你想看哪两个包之间的间隔,直接读那一行的值就行。
如果要做更精确的时序分析,可以打开"统计 - 流量图"或者"统计 - 对话",把 UDP 会话按时间轴铺开,包之间的间距一目了然。对于排查"为什么某个实时应用有抖动"这类问题,时间间隔的分布比单个间隔值更有参考价值——偶尔一个大的间隔和持续的大间隔,含义完全不同。
要提醒的是,tcp.analysis.ack_rtt这类字段只对 TCP 有意义,因为它是根据握手和 ACK 的时序算出来的往返时延。UDP 是无连接的,没有 ACK,所以只能靠相邻包的时间戳自己做差。如果你需要严格测量两包间隔并导出,可以把这个字段手工加进自定义列,方便对比。
3.3 只显示某网卡发送源的字节内容:用"导出"和自定义列
还有一个常见需求是"只看某个以太网发送源的数据包的字节内容"。这在 Wireshark 里分两步。
第一步是把源端筛出来,用以太网层的地址过滤,比如eth.src == 00:11:22:33:44:55。注意这是 MAC 地址层面的过滤,和 IP 层的ip.src不是一回事。一个设备可能有多个 IP,但它的 MAC 是固定的,所以按 eth.src 筛能稳定定位到某块网卡发出的帧。
第二步是看字节内容。点开任意一个包,在下方的字节面板里能看到从以太网头开始的十六进制原始数据。如果要把内容导出来,选中需要的包,用"文件 - 导出指定分组",可以选导出成纯文本、CSV 或十六进制,只要在导出的选项里勾选你需要的字段就行。默认导出格式会把关键字段列出来,但要看到完整的原始字节,选"Packet Bytes"这一项。
如果你经常要看某个字段的原始字节,可以在数据包详情面板里右键那个字段,选"作为十六进制显示"或者"应用为列",把它直接固定到列表里。这样每一行的这个字段都会以字节形式展示,比点开一个个包快得多。
4. 对着一个完整会话,看 TCP 到底发生了什么
4.1 三次握手、重传和乱序的判读
拿到一堆 TCP 包之后,Wireshark 会自动做序列号分析,这一点非常省心。你只要在过滤器里写tcp,然后右键任意一个包选"追踪 TCP 流",它会把这个会话的所有包串起来,并且按方向分色显示。这是排查单个连接问题最快的方式。
三次握手的判读核心就三个包:SYN、SYN+ACK、ACK。正常的时候,第一个 SYN 发出后,几百毫秒内就会收到 SYN+ACK。如果 SYN 发了没人理,一直重试,说明对端不可达或者被防火墙静默丢弃;如果收到的是 RST,说明对端端口没开或者直接拒绝。这两种情况在排查里含义完全不同,不能笼统说"连不上"。
重传就更值得看。Wireshark 会把重传的包标成红色并打上tcp.analysis.retransmission标记。偶发一两个重传很正常,但如果同一个包反复重传,基本可以断定中间有丢包或者链路质量差。这里有个坑:有时候看到"重传"其实不是真重传,而是抓包点位置导致的假象。比如你在发送端抓包,看到包重传了,但你没法确认它到底丢在哪个环节。要定位丢失位置,得在链路两端同时抓,对比谁没收到 ACK。
乱序包(tcp.analysis.out_of_order)看着吓人,但在现代网络里很常见,不一定影响性能,因为接收端会重新排序。只有大量乱序持续出现,才需要考虑是不是多路径或者链路问题。
4.2 借"专家信息"和"统计"两把刀快速定位异常
包一多,一个个看是不现实的。Wireshark 左下角有个彩色圆点,那是"专家信息"的入口,点开它会按严重程度列出所有异常:错误、警告、注意。这一步几乎是我的固定动作,先看专家信息,能把大部分明显的问题揪出来。
再结合顶部"统计"菜单里的几个工具。想找哪个 IP 最活跃,看"会话";想看协议占比,看"协议分级";想排查慢在哪一步,看"服务响应时间"。这几个视图不用一个个点包,直接给你汇总好的排序结果,效率高很多。
我自己的排查顺序基本固定:先看专家信息列出的错误,再用会话表找到流量最大的几个对端,然后针对可疑会话追踪 TCP 流,最后回到具体包看应用层内容。这套顺序能把"从几万个包里找问题"变成"按图索骥"。
5. HTTPS 流量怎么分析,以及 TLS 解密的实际边界
5.1 默认看不到明文,是因为流量本来就是加密的
Wireshark 抓到的 HTTPS 包,传输层以上是 TLS 密文,应用层内容看不到,这不是软件的问题,是加密设计的必然结果。你抓到的只是 TLS 记录层的外壳,能看到的只有握手信息、证书、SNI 这些不加密的部分。
能看到的握手信息其实已经能说明不少问题。TLS 握手里包含了客户端和服务端协商的密码套件、TLS 版本、SNI 主机名、证书链。如果出现握手失败、证书错误,这些都能在握手包里直接看到。很多"网站打不开"的问题,根因就在握手阶段,还没到应用层就断了。
5.2 用密钥日志文件解密自己流量的完整操作
如果你在调试自己开发的服务,想看 TLS 加密后的应用层内容,正规做法是让客户端把会话密钥导出来,Wireshark 拿这份密钥去解密。这仅限于你自己的流量、你授权的环境,别拿它去处理别人的数据。
具体做法:以 Chrome、Firefox、Edge 这类主流浏览器为例,设一个环境变量SSLKEYLOGFILE,指向一个文本文件,比如C:\keys\sslkeylog.txt。设完重启浏览器,之后浏览器访问 HTTPS 时会把每次会话的密钥追加写到这个文件里。然后打开 Wireshark 的"首选项 - 协议 - TLS",把"(Pre)-Master-Secret log filename"指向同一个文件。
配置好之后,重新抓一次访问流量,TLS 解出来的应用层内容就能正常显示了。要注意几点:密钥日志是浏览器新会话才生成的,配置之前的旧流量解不了;不同浏览器的支持程度不一样,有些需要特定版本;另外这个文件包含会话密钥,属于敏感信息,用完及时删掉,别随手传给别人。
如果抓的是普通网页内容而只是想快速看结构,Fiddler、Charles、Burp Suite、Reqable 这类中间人代理工具可能更顺手——它们通过给自己签发的证书来解密流量,配置好证书后界面更面向应用层。但这类工具也有各自的门槛,比如手机上装证书总显示未知、小程序抓包证书不生效等,本质上是证书信任链没配对。选哪类工具取决于你的场景:纯协议学习、看底层时序,用 Wireshark;看具体的 HTTP 请求响应内容,代理工具更高效。
6. 那些教程不写、但实际一定会踩的坑
6.1 "为什么只能显示几百字节数据"的真相
有人遇到抓包只能显示部分字节、后面被截断的情况,这基本就是快照长度(snaplen)设小了。在捕获选项里如果把这个值设成了几百,比如 520,那每个包最多只记录这么多字节,剩下的全被裁掉。解决方法很简单:在"捕获 - 选项"里把 snaplen 设回默认的大值,或者直接找个明确的"snaplen"输入框填 262144 或者更大。
还有一种"字节不够"的错觉来自应用层分片,比如一个大的响应被拆成多个 TCP 包,每个包单独看都不长,但拼起来才是完整内容。这时候用"追踪 TCP 流"看拼接后的完整数据,就不会被单包长度误导了。
6.2 长时间抓包怎么不把内存撑爆
抓包最怕两种情况:一是抓了几个小时,软件内存爆掉;二是抓了一堆无关流量,回头看的时候无从下手。解决办法是开环形缓冲区。
在"捕获选项"里有个"输出"标签页,勾选"Create a new file automatically",设置成每达到一定大小或者一定时间就新建文件,同时限制保留的文件数量。这样它会循环覆盖旧文件,内存和磁盘都不会失控。比如设成每个文件 50MB、最多保留 10 个,长期挂着也不怕。
如果只是短时间盯一个问题,那就别长时间抓。抓到关键复现的瞬间立刻停止,截取时间窗口,反而更好分析。我自己的习惯是抓之前先想清楚"我要复现什么动作",然后只在这个动作前后抓十几秒,包少、干净、定位快。
6.3 抓不到包时的排查链路
抓不到包是新手最焦虑的情况。按顺序排查,基本都能找到原因。
先确认网卡选对了没有。多网卡机器最容易选错,明明走的是无线,却选了有线。可以在命令提示符里先确认当前活动的接口。
再确认过滤器是不是写得太严。捕获过滤器写错会静默失效,直接抓不到任何东西。把过滤器清空试一次,如果立刻有包了,就是过滤器的问题。
然后看是不是本地回环流量。访问本机服务走的是回环,普通网卡抓不到,需要环回适配器。
最后看权限和驱动。有些系统下 Npcap 没正确加载,或者被安全软件挡住,表现就是接口列表异常或者抓到的全是空的。重装 Npcap、以管理员身份运行,通常能解决。
如果是想抓整个局域网的流量却发现只能看到广播,那这不是故障,是交换网络的正常行为,得靠端口镜像或者在上游抓,前面 2.1 节已经说过。
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 完全没有包 | 网卡选错 / 捕获过滤写错 | 清空过滤重抓,核对活动网卡 |
| 只有部分字节 | snaplen 设小 | 恢复默认快照长度 |
| 抓不到本地服务 | 走了回环 | 用环回适配器 |
| 看不到其他主机流量 | 交换网络限制 | 配置端口镜像 |
| 无线管理帧看不到 | 未进入监听模式 | 换支持监听模式的网卡和驱动 |
我自己的体会是,抓包这件事,工具本身不难,难的是"抓之前把问题想清楚"。你要抓哪台机器的流量、哪个协议的、大概什么时间发生、复现条件是什么,把这几个问题先答一遍,再去点抓包按钮,效率会比盲目录一整天的流量高太多。还有一个小建议:每次抓完,用"文件 - 保存"存成一个带日期的 pcapng 文件,重要的问题现场留着,后面复盘、对比、找规律都用得上,别抓完一关就没了。