Wireshark抓包统计发送数据包长度:从帧长到流量分析实战
2026/9/19 18:27:33 网站建设 项目流程

Wireshark抓包之统计发送的数据包长度

抓包容易,看包难;看包容易,看明白更难。很多人拿到 Wireshark,打开一个 pcapng 文件,第一反应就是对着几万条报文发呆:到底哪条是我发出去的?发了多少个包?每个包多大?总流量占了多少?今天这篇就专门解决这个问题,把“统计发送的数据包长度”这件事从头到尾拆开讲清楚。

先说一下我为什么要专门写这个主题。前阵子帮朋友排查一个云端接口超时问题,两边程序都说是网络慢,开发小哥甩过来一个抓包文件,问我能不能告诉他“客户端往服务端到底发了多少数据”。这种需求在故障排查、性能分析、协议对接里太常见了。Wireshark 自带的统计功能完全可以回答,但很多人不会用,或者只会看一眼“Summary”,稍微复杂一点的需求就卡住了。这篇文章适合刚接触抓包的新人,也适合那些已经会用基本过滤、但没深入研究过 Statistics 菜单的工程师。看完之后,你至少能自己回答这三个问题:发送方向一共多少字节?包长分布长什么样?某个时间段的发送速率是多少?

1. 先搞清楚“包长”到底指哪一层

1.1 长度列背后藏了至少三个数字

我第一次看 Wireshark 的时候,以为列表里那个 Length 列就是“包大小”,直到有一次拿它跟交换机流量统计对不上账,才认真研究了一下。Wireshark 默认显示的 Length 列,指的是捕获文件里的帧长度(frame length),也就是从以太网帧头开始算起的大小。但如果你按下 Ctrl+Alt+Shift+T 或者点开一个包的详情,会发现还有好几个长度概念:

  • 帧长度(Frame Length):物理线路上传输的完整帧大小,通常包含以太网头部、IP头部、传输层头部和载荷。如果是 VLAN 报文,这里还会多出 4 字节的 802.1Q Tag。
  • IP 包长度(Total Length):IP 头里专门有一个字段记录这个 IP 包的总长度,单位是字节,包含 IP 头本身。注意它不包含以太网头部,所以正常来说 IP Length 会比 Frame Length 小 14 字节(不含 VLAN 时)。
  • 上层数据长度(TCP Len / UDP Length):比如 TCP 段的 Length 字段只是指 TCP 载荷的大小,不包含 TCP 头;而 UDP 的 Length 字段又包含了 UDP 头 8 字节。

所以当你问“这个包多大”,必须先定义清楚是哪一层的长度。我们统计“发送的数据包长度”,我个人习惯默认按 Wireshark 列表里的 Length 列来统计,也就是完整帧长,因为它最接近真实网卡发出的字节数,跟对端抓包、交换机端口计数器也比较容易对齐。如果你关心的是应用层有效数据,那就得用tcp.len或者data.len这类显示字段来过滤和计算,否则会把协议头开销也算进去,数据对不上。

1.2 统计发送方向的两个核心过滤思路

明白了层次,第二步就是怎么定位“发送方向”。抓包文件里每个包都有源地址和目的地址,你要统计“发送”,本质上就是区分哪些报文是你关注的这台主机发出去的。最常见的写法是以本机 IP 为准:

ip.src == 192.168.1.100

这个显示过滤器会把源 IP 是 192.168.1.100 的所有包筛出来,包括本机发出的 TCP SYN、HTTP 请求、Ping 请求等。如果要看接收方向,就用ip.dst == 192.168.1.100。有些场景更复杂,比如有两个设备 A 和 B,你想统计“A 发给 B”的所有数据,那就写成:

ip.src == 192.168.1.1 && ip.dst == 192.168.1.2

这里要特别提醒一个新手常犯的错误:不要默认ip.src就等于发送方向。如果抓包位置在路由器或者交换机镜像口上,一个包从客户端到服务器,对于抓包点来说可能是“从端口 A 进来、从端口 B 出去”,但它的 IP 源地址始终是客户端。所以“发送”要看 IP 层源地址,或者更严谨一点,结合以太网源地址eth.src来判断真正从哪个物理接口发出来的。

2. Statistics 菜单里那些和包长有关的入口

2.1 从 Protocol Hierarchy 到 Packet Lengths

Wireshark 的 Statistics 菜单功能非常密集,很多入口第一眼不知道干什么用。我按平时使用频率从高到低排个序,让你有个整体印象。

先说Statistics -> Protocol Hierarchy,这个窗口会按协议层级展示每个协议的帧数、字节数和端到端的字节占比。它的价值在于快速看“占比”:如果发现某种协议占了 90% 的字节,那后续再细化分析就有方向了。但它不区分方向,所以只能做总量参考。

然后是Statistics -> Packet Lengths,这才是统计包长分布的正主。它会自动把全部包按长度区间分组,常见分组是 40-79、80-159、160-319、320-639 等,每组显示包数、百分比、累积包数、累积百分比。默认统计的是帧长,但你也可以在对话框里调整长度单位的设置,选择按字节统计、按比特统计,甚至按报文里的特定字段统计。它同样不区分方向,所以你得先在外层设置好显示过滤器,再打开 Packet Lengths,统计结果才会按过滤后的包来算。

Statistics -> ConversationsEndpoints则适合按会话和端点维度看字节数。比如我想知道本机和某个服务器之间到底互相发了多少字节,打开 Conversations,选中 TCP 页签,找到那对 IP 地址,A->B 和 B->A 的字节数分列显示,非常直观。这个功能虽然不直接叫“包长统计”,但实际工作中我经常靠它快速判断哪个会话流量大。

2.2 Capture File Properties 里有个隐藏关键点

遇到“统计结果和实际不符”的问题,我第一步一定是打开Statistics -> Capture File Properties,看中间有一项叫 “Snapshot length”(快照长度)。这是抓包时刻每个报文实际被捕获的长度上限,也叫 snaplen。

比如很多人抓包时网卡默认设置了 520 字节的快照,那么超过 520 字节的实际报文,在文件里只保留了前 520 字节,Wireshark 的 Length 列就会显示 520,而不是真实长度。这种情况下,你做任何包长分布统计、字节数统计,得到的结果都会偏小,而且是系统性偏小。这个细节在后面常见问题部分我会展开讲,这里先埋个伏笔。

3. 统计发送数据包长度的完整实操流程

3.1 用 Packet Lengths 快速拿到“发送包长分布”

假设我已经抓好了一个文件,本机 IP 是 192.168.1.100,现在要看“这台机器发送方向的数据包长度分布”。操作步骤如下:

第一步,在 Wireshark 主界面的显示过滤器栏输入:

ip.src == 192.168.1.100

回车之后,列表里就只保留本机发出的报文。第二步,点击菜单Statistics -> Packet Lengths,弹出分布表。表格第一列是长度区间,比如 “40-79”、“80-159” 等,第二列是该区间包数,第三列是该区间占过滤后总包数的百分比。这一步基本零门槛,十秒钟就能得到结论。

但如果抓包文件很大、有几十万条报文,显示过滤器计算会有点慢,我通常会先加一个更精确的过滤条件,比如只想看 TCP 层发出的数据包:

ip.src == 192.168.1.100 && tcp

或者只想看某个特定端口,避免 ARP、DNS 等混杂流量干扰:

ip.src == 192.168.1.100 && tcp.port == 443

Packet Lengths 的分组粒度比较粗,如果你需要精确到每个包的具体长度分布,可以用tshark导出每个包的长度,再用 Excel 或脚本来做精细统计。后面我专门讲命令行方案。

3.2 用 IO Graphs 看“发送字节数随时间的变化”

分布表只能告诉你长什么样,没法告诉你什么时候发送量大。想回答时间维度的问题,就要用Statistics -> IO Graphs

IO Graphs 是一个折线图工具,默认显示“所有包”的速率。我习惯这样配置:在显示过滤器里输入ip.src == 192.168.1.100,然后在 IO Graphs 窗口里把该条曲线的 Y 轴单位从 Packets 改成 Bytes,这样折线就表示每个时间间隔内发送的总字节数。如果觉得 1 秒粒度太粗,可以把 Interval 改成 100ms 甚至 10ms,能更清楚看到突发流量。

这里有个技巧:Y 轴还可以选SUM(*)之类的聚合函数,配合显示过滤器可以做出很多花样。比如我想分别看“发送的 TCP 载荷字节”和“发送的 IP 总字节”两条曲线,可以建两条曲线,一条过滤器写ip.src == 192.168.1.100 && tcp.payload,另一条写ip.src == 192.168.1.100,Y 轴都设为 SUM(*) 或 Bytes。两条线之间的差距就是 TCP 头 + IP 头 + 以太网头的开销。

IO Graphs 的曲线默认是对整个文件起作用,但窗口最下方有个 “Display Filter” 输入框,如果你在这里再写一个过滤条件,那么只有符合这个条件的包才会被计入曲线。比如写ip.src == 192.168.1.100 && tcp.port == 443,曲线就只统计发往 443 端口的流量。

3.3 用 tshark 命令行算平均包长和总量

图形界面够用了,但如果你要处理几十个 pcap 文件,或者想写脚本自动统计,那还是tshark更顺手。tshark 是 Wireshark 自带的命令行工具,装了 Wireshark 就会一起装上,在终端直接调用。

比如我要统计本机发送方向的包总数和总字节数,最快的方式是用-q静默模式和-z io,stat统计模块:

tshark -r capture.pcapng -q -z io,stat,0 -Y "ip.src == 192.168.1.100"

输出里会有一行| Frame: 12345 | 12345678 |之类的结果,第一数字是包数,第二个是总字节数。但这里统计的字节数默认是帧长度,与抓包时是否截断直接相关。

要算平均包长,可以分两步:先拿到总字节数,再拿到总包数,除一下就是平均帧长。也可以通过 tshark 自带的 TShark 字段打印:

tshark -r capture.pcapng -Y "ip.src == 192.168.1.100" -T fields -e frame.len

这会输出一行一个数字,把这些数字导入 Excel 或者 Python 里做分布统计、排序统计都很方便。我自己写过一个简单的 Python 脚本,读取frame.len后用 numpy 直接算均值、中位数和 95 百分位,在评估某个协议是否容易触发 MTU 分片时特别有用。

4. 一个真实场景:网页访问时“发送方向”到底发了多少

4.1 场景设定与抓包准备

理论讲了一堆,还是用一次常见的网页访问全过程来演示。假设我在浏览器里访问http://example.com,本机 IP 是 192.168.1.100,对端服务器 IP 是 93.184.216.34,网关和 DNS 各干各的。我提前在 Wireshark 里设置好显示过滤器ip.addr == 192.168.1.100 or ip.addr == 93.184.216.34,避免无关流量混进来,然后开始抓包,刷新页面,等页面加载完毕,停止抓包。

这个抓包文件里包含了我方发出的 DNS 查询、TCP 三次握手、HTTP GET 请求,以及服务端返回的响应数据。现在要严格回答“我这一侧发送方向总共发了多少数据、包长分布如何”。

4.2 双重过滤确认纯发送方向

有人会问:为什么不在抓包开始前就设置捕获过滤器,而要在显示过滤器里慢慢筛?因为捕获过滤器会在抓包时就把不符合条件的包丢掉,万一之后发现想看的流量没抓到,就没办法补救了。所以我一般建议“抓全一点,显示时再筛”,除非流量大到你完全不关心其他东西。

先删除之前加的总过滤器,重新输入:

ip.src == 192.168.1.100

列表里剩下的就是本机发出的包。此时再做一步细化,只看和这个网站交互相关的,排除 DNS 查询可能产生的干扰:

ip.src == 192.168.1.100 && tcp.port == 80

对于普通的 HTTP 访问,这种方法比较直接;如果是 HTTPS,则把端口改成 443 即可。

4.3 统计结果解读与细节确认

在过滤好的视图下打开 Packet Lengths,通常会看到两部分:一部分是很小的包(40-79 字节区间),对应 TCP 三次握手的 SYN、SYN-ACK、ACK,还有 HTTP 请求发送结束后的小 ACK;一部分是稍大的包(具体大小取决于 GET 请求头长度和 Cookie 长度)。如果页面里有上传操作,还会看到接近 1460 字节的包,那说明应用层数据已经超过了单包承载能力,需要多次发送。

再用 IO Graphs 打开,设置好 Y 轴为 Bytes,能明显看到发送流量的尖峰集中在页面请求发出的那一刻。如果你在同一个图表里再加一条接收方向的曲线,两条线对比起来,就能很直观地看出“发送的小、接收的大”这种典型的读多写少模式。

如果我想精确知道发送方向的总字节数,最快的方法是Statistics -> Capture File Properties上方其实没有按方向统计,所以要靠 Conversations。打开 Conversations,切换到 TCP 页签,找到本机与 93.184.216.34 的那一行,A->B 一列就是发送方向的字节总数,B->A 是接收方向。这个数字和 Packet Lengths 的分布在细节上可能略有差异,但总量是能对上的。

5. 常见问题排查与避坑指南

5.1 为什么 Wireshark 只显示 520 字节,怎么显示完整的 2090 字节

这个现象非常典型,搜“wireshark 为何只能显示520字节数据”的人一大堆。两种情况最常见:

第一种是抓包时把快照长度设小了。在 Capture Options 里,你可以给每个接口设置 “Limit each packet to” 的字节数,比如设置了 520,那么任何超过 520 字节的包都只会记录前 520 字节,列表里的 Length 列显示为 520,后面不管真实长度是 1500 还是 2000,通通看不到。解决办法是回到抓包这一步,把“Limit each packet to”关掉或改成 65535,重新抓一次。

第二种是对方设备或交换机的端口镜像本身做了截断。有时候运维在交换机上做镜像时,担心镜像流量太大,会设置一个 mirror 报文截断长度,比如 128 字节或 520 字节。这种情况下,就算 Wireshark 设置完整抓包,收到的包也是被截过的。解决办法是修改交换机上的镜像配置,把截断长度改成不限制,或者至少改成大于 MTU 的值。

那如果已经有了一份被截断的 pcap 文件,还能不能恢复出真实的 2090 字节?很遗憾,直接看是不行的,数据没抓进来就没法从文件里变出来。但有一种例外:TCP 场景下,如果抓包文件里保存了足够多的连续 TCP 段,Wireshark 的“Follow TCP Stream”可以通过重组还原出完整的应用层数据流,这跟单包长度统计是两码事。所以遇到这种文件,我通常先看看能不能做 TCP 重组,而不是死磕包长统计。

5.2 Length 列显示 1514,但 IP 层只有 1500,差在哪

这是另一个让人挠头的问题。以太网标准 MTU 是 1500,意思是 IP 层最大载荷是 1500 字节,但以太网帧头还有 14 字节,所以一个完整的不带 VLAN 的帧长度是 14 + 1500 = 1514 字节。如果带了 VLAN 标签,还要再加 4 字节,变成 1518 字节。很多抓包工具还会额外记录 4 字节的 FCS 校验和,于是你看到 1522 也不是怪事,取决于驱动和抓包工具的设置。

所以当你统计发送方向的包长时,如果看到一堆 1514 的包,说明应用层数据已经撑满了 MTU,这是大流量传输的正常表现。如果你看到的是 2090、4054 甚至更大的长度,那基本可以断定这个抓包环境里有巨型帧(Jumbo Frame),或者网卡做了 LRO/GRO 合并,这种情况下 IP 层分片逻辑、TCP 校验和计算都会跟标准 MTU 环境不同,统计时要注意区分。

5.3 同一份抓包,Packet Lengths 和 ip.len 统计结果对不上

有次我帮同事统计数据包长度分布,他用ip.len作为长度字段,我用frame.len,两个人算出来的平均包长差了 14 字节。其实谁都没错,只是统计口径不同。frame.len是帧长,包含以太网头;ip.len是 IP 总长,不包含以太网头。对于不带 VLAN 的标准以太网帧,两者之间差一个固定的 14。

我的建议是:如果是跟对端设备、交换机流量对比,尽量用frame.len;如果是做 IP 层或传输层性能分析,用ip.lentcp.len。关键是整个统计过程保持口径一致。团队协作时,最好在统计结果旁边注明你用的是哪个字段,避免后面接手的人误解。

5.4 抓包文件很大,统计一下卡死怎么办

超过 1GB 的 pcap 文件在图形界面里开 Packet Lengths,确实有可能会卡顿。我的处理办法是先用tshark做一次裁切,把发送方向的包单独导成一个小文件:

tshark -r big.pcapng -Y "ip.src == 192.168.1.100" -w send_only.pcapng

然后对这个小文件再做图形化统计,流畅很多。如果需要按时间切片,可以用-Y "frame.time >= \"2024-01-01 00:00:00\" && frame.time < \"2024-01-01 00:05:00\""来切出一段窗口,再统计,就不必等图形界面慢慢算。

5.5 重传、乱序和分片包会不会影响统计

会,而且影响比你想象的大。TCP 重传包在 Wireshark 里会被标记为TCP Retransmission,这些包的实际数据是对之前某个包的重复发送。如果你的目标是统计“应用层实际发送的有效载荷”,那重传包不应该算进去;但如果你想统计“这台机器网卡实际发出的字节数”,那重传包必须算,因为它确实占用了带宽。两者的业务含义不同,统计前要想清楚。

IP 分片也是类似。一个 3000 字节的 IP 包在以太网上会被分成两个 1500 字节左右的片段,Packet Lengths 统计会看到两个接近 1514 的包,但如果你用ip.len == 3000去过滤,则一个都匹配不到,因为分片后每个片段的 IP 头里的 Total Length 只是分片自身的长度,总长度信息在第一个分片的偏移字段里才能拼出来。因此做包长分布统计时,不要指望 ip.len 能精确代表应用层消息大小。

6. 我的几个独家心得

6.1 先看总体,再分方向,最后看时间线

很多人一上来就直接套过滤条件,结果漏掉了关键信息。我的习惯是三步走:先打开 Protocol Hierarchy 看整体协议构成和字节量;再打开 Conversations 和 Endpoints 看哪些 IP、哪个端口在消耗流量,快速锁定方向;最后才用 Packet Lengths 和 IO Graphs 深入统计具体长度分布和时间趋势。这套流程在绝大多数网络故障里都够用,而且不会因为过早过滤而错过异常报文。

6.2 保存一套自己的显示过滤器模板

统计发送方向包长这种过滤条件,值得存成 Wireshark 的显示过滤器按钮。操作很简单:在显示过滤器栏输入ip.src == 192.168.1.100,点击左侧的“书签”或者“保存”按钮,给它起个名字叫“本机发送”。下次抓到新文件,点一下这个按钮就自动应用了。办公网环境里本机 IP 可能会变,所以我的模板通常写成变量,比如ip.src == $MYIP,通过过滤表达式对话框配置好变量值,这样换环境也能直接套用。

6.3 统计工具是死的,统计口径是活的

最后分享一个容易被忽视的经验:Wireshark 只是工具,它给出的所有统计数字在离开具体场景前都没有绝对意义。同样是“发送数据包长度”,在做弱网模拟时,你关注的是小包和重传包的占比;在做带宽规划时,你关注的是总字节数和峰值速率;在定位 MTU 分片问题时,你关注的是 1500 附近的包有没有被截断。所以我的建议是:每次统计前,先问自己一个问题——“这个数字算出之后我要拿它做什么决策?”想清楚答案,统计口径自然就对了。

包长大小的统计这活儿,熟练之后五分钟就能跑完一轮,但真正值钱的不是你点了哪几个菜单,而是你看见数字之后能判断出系统状态正不正常。写这篇文章的时候,我脑子里一直想的是以前踩过的那些坑:被 520 字节快照坑过,被 ip.len 和 frame.len 口径不一致坑过,也被重传包重复计数坑过。这些坑其实都能用一套清晰的流程绕过去:先看总体,再分方向,再按时间轴细看,全程保持统计口径一致。希望这篇能让你少走点弯路,下次再遇到“帮我看看这个抓包文件里发了多少数据”的请求,你能底气十足地说:“十分钟,给你一份完整的发送方向包长统计报告。”

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询