ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Wireshark统计发送数据包长度:字段选择、过滤器与避坑指南

Wireshark统计发送数据包长度:字段选择、过滤器与避坑指南 Wireshark抓包之后总是有人问我同一个问题怎么统计本机发出去的数据包到底有多长这个问题看着简单真要动手统计的时候坑却一个接一个。有人统计了半天发现收发混在一起有人被TSO产生的超大假包骗了还有人拿着ip.len当成了应用层载荷长度。这篇文章就专门把“统计发送数据包长度”这件事从头到尾捋一遍包括字段怎么选、过滤器怎么写、GUI哪里看、命令行怎么算以及我踩过的几个典型坑。适合刚接触Wireshark的测试同学、做协议开发的工程师以及所有需要拿数据说话的运维和安全分析人员。1. 为什么统计发送数据包长度能看出这么多问题1.1 数据包长度背后是协议行为网络数据包的长度不是随机的。以太网MTU默认1500字节IP头一般20字节TCP头一般20字节所以一个满载的TCP数据帧在Wireshark里通常会显示为1514字节14字节以太网头加上1500字节IP报文。如果你的抓包里发送方向满是这种接近MTU的大包说明应用在尽力把数据塞满每一个报文属于典型的批量传输行为。反过来如果发送方向全是几十字节的小包那通常意味着交互式请求、控制消息或者应用层没做好数据聚合一次write就发一个包。数据包长度分布还能反映很多隐藏问题。举个例子同样是一秒钟发送1000个包如果这1000个包的平均长度只有80字节实际吞吐只有640Kbps左右但如果平均长度是1400字节吞吐就能到11Mbps以上。只看包数不看长度很容易得出完全错误的结论。1.2 实际场景里统计包长能干什么我做协议适配和性能排查时统计发送数据包长度主要用在三个地方。第一个是性能问题定位。用户反馈上传慢在客户端抓包统计发送方向的包长分布基本一眼就能看出来问题出在客户端还是网络链路。如果客户端发的都是满载大包说明组包没问题瓶颈大概率在链路质量或服务端处理能力如果客户端疯狂发小包那就是应用层或TCP参数的问题比如Nagle算法和延迟确认互相等待。第二个是协议开发调试。做自定义二进制协议联调时经常要确认一个业务消息是不是按预期封装成了一个数据包发出。统计一下发送方向所有包长度观察长度分布有没有出现异常的零散值比一条条翻包高效得多。第三个是安全与异常检测。异常流量的包长分布通常是很有特征的。比如某些隐蔽通信为了固定包长会故意把数据填充到固定大小导致长度分布出现异常的尖峰又比如扫描行为往往伴随大量小包。做这类分析时发送方向的包长统计往往比接收方向更能说明问题因为它代表的是本机主动行为的特征。2. 抓包前必须想明白的事什么是“发送”的长度2.1 选对接口抓本机流量不需要混杂模式很多第一次抓包的同学会纠结一个事儿要不要在抓包选项里勾选混杂模式这里说清楚抓本机主动发出的包不需要开混杂模式。网卡驱动本来就会把本机发出的包交给抓包程序混杂模式解决的是抓取经过本机网卡但目的地不是本机的流量比如接交换机镜像口抓其他设备的包那种场景才必须开。接口选择上如果测的是普通网络应用选有线网卡或无线网卡对应的接口就好如果应用是回环通信比如本机服务访问本机服务要抓Loopback接口。很多人在这步就翻车了抓了半天全是发给别人的包还奇怪怎么找不到自己的业务流量。2.2 frame.len、ip.len和tcp.len的区别必须搞清统计“数据包长度”首先要定义清楚统计的是哪一层长度。Wireshark里最相关的字段有四个容易混。字段含义无VLAN、无IP选项、无TCP选项时的典型值frame.len整帧长度从以太网头开始算不含前导码和FCS1514ip.lenIP报文总长度包含IP头和IP载荷不含以太网头1500tcp.lenTCP载荷长度不包含TCP头和IP头1460udp.lengthUDP报文长度包含UDP头8字节和载荷按应用而定一个典型的满载TCP包四个字段的关系就是1514等于14加15001500等于20加20加1460。这个等式看着简单但实际统计时经常有人用错字段。我见过有人拿着ip.len当应用层数据量上报结果把20字节TCP头和20字节IP头都算进了业务数据里几十万条流量算下来误差不小。需要额外注意VLAN场景。如果抓到的包带802.1Q标签帧里会多出4字节frame.len会变成1518但ip.len仍然是1500。统计时如果不说明口径对接的人看到1518和1514对不上还得解释半天。2.3 用显示过滤器精确锁定发送方向Wireshark本身不会给每个包标一个“发送/接收”方向给你过滤判断方向要自己通过地址来区分。最常用的方法就是用源地址过滤本机发出的包源IP是本机IP所以显示过滤器写成ip.src 本机IP统计出来的就是发送方向的包。这里有个高频错误把过滤器写成ip.addr 本机IP。ip.addr的意思是“只要源或目的任意一个匹配”等于把接收方向的包也全部包含了进来。一个典型的交互会话里接收方向通常是大量ACK小包一旦混进来整个统计就失真了。所以只要是想统计“本机发出去的包”就坚持用ip.src。还有一个边界情况需要知道ARP这类协议没有IP头ip.src过滤会把它们全部滤掉。如果统计目标是“本机发出的所有以太网帧”包括ARP、DHCP这种特殊报文那就改用eth.src 本机MAC地址。大多数业务场景用ip.src就够了但做底层协议分析时这个区别很关键。另外抓包过滤器和显示过滤器是两套东西。抓包阶段可以在Capture Options里用BPF语法提前过滤比如src host 192.168.1.23好处是文件小、抓包性能好缺点是语法不同经常有人把显示过滤器抄到抓包过滤器里导致语法报错。我的建议是如果只想事后统计直接在显示过滤器里过滤就够了反而更灵活。3. 图形界面五分钟完成数据包长度统计3.1 第一站Capture File Properties看总览抓到包之后最快的一组数字在Statistics菜单下的Capture File Properties里老版本也叫Summary。这个窗口会给出整个文件的包总数、总字节数、平均包长、平均每秒包数等信息。需要注意的是这里的指标默认是基于当前显示过滤器的。也就是说你先把过滤器写成ip.src 本机IP再打开Capture File Properties看到的才是发送方向的总包数和平均包长。很多人直接打开这个窗口看平均包长其实统计的是收发混合的全量流量数据意义完全不一样。平均包长能一眼看出流量特征如果平均包长在800字节以上说明流量以大包传输为主通常是文件传输、视频流这类业务如果平均包长只有一百多字节那就是典型的小报文交互比如心跳、协议协商、证券行情这类。3.2 Packet Lengths表最直接的包长分布答案Statistics菜单下有一个Packet Lengths这个表是我做包长统计用得最频繁的功能。它会按长度区间显示当前过滤条件下每个区间的包数、占比和累计占比默认区间大致是40到79、80到159、160到319、320到639、640到1279、1280到2559这样不等宽划分。用这个表看发送方向的数据包长度分布非常直观。比如上传大文件时你会看到1280到2559区间的包占比极高这是满载传输的正常特征如果看到40到79区间占比很高说明有一大堆纯ACK小包或者应用没有把数据攒够再发送。这个表还有个很实用的联动功能选中表里的某个区间主窗口会同步高亮对应的包双击某一行Wireshark会直接跳到第一个属于该区间的包。这样当你发现某个长度区间异常时能立刻翻到实际的包去检查具体内容排查效率高很多。3.3 IO Graph把长度变化画成曲线Packet Lengths表给的是一个静态分布而IO Graph能给的是长度随时间变化的趋势。Statistics菜单下的IO Graph支持配置多条曲线每条曲线都可以有自己的过滤器。统计发送数据包长度时我习惯配置两条曲线一起看。第一条过滤器写ip.src 本机IPY轴单位选“SUM(bytes)”这样看到的是发送字节速率第二条过滤器还是ip.src 本机IP但Y轴单位选“COUNT(packets)”看到的是发送包速率。两条曲线叠加后如果字节速率很高而包速率很低说明是大包传输如果包速率高但字节速率低就是小包风暴。这两种情况对性能的影响是截然不同的。IO Graph的参数需要根据抓包时长调整。时间粒度太大会把峰值抹平粒度太小会显得杂乱。我一般先按默认值看整体趋势再放大到出现异常的时间段仔细看缩放时用鼠标拖选区域就够了。3.4 自定义列日常排查最顺手的方式如果只是想偶尔看一眼某几个包的长度不需要专门开统计窗口直接在Wireshark主界面自定义列就够了。在列标题上右键选择Column Preferences添加几个新列frame.len、ip.len、tcp.len。这样每一行包都直接显示三个长度值配合ip.src 本机IP过滤前后翻包对比非常方便。主界面状态栏还有一个容易被忽略的信息当你用显示过滤器过滤之后右下角状态栏会显示“Displayed: 1234 (456789 B)”这个括号里的字节数就是当前过滤条件下所有包的总字节数。这就是最简单的发送字节总量统计随手就能看不用开统计窗口。不过GUI始终有个局限它只给你总数和分布不直接给你分位数。要算P95、P99这类指标还得把数据导出来处理这就用到下一节的TShark方案了。4. 用TShark把统计做到“可复现”4.1 把包长字段导出成文本图形界面点出来的统计结果不容易复现也很难和别人共享。我更习惯用TShark把长度字段导出来再交给脚本处理这样每次分析都有一份可复查的中间产物。基本导出命令如下tshark -r send.pcapng -Y ip.src 192.168.1.23 -T fields -e frame.len send_lens.txt参数含义不复杂-r指定读取的抓包文件-Y指定显示过滤器-T fields表示按字段输出-e frame.len指定要导出的字段。你可以一次导出多个字段比如同时把源IP也导出来方便检查是不是混入了其他源tshark -r send.pcapng -Y ip.src 192.168.1.23 -T fields -e frame.len -e ip.src send_lens.txt如果想直接导出CSV给命令加上-E headery和-E separator,tshark -r send.pcapng -Y ip.src 192.168.1.23 -T fields -e frame.len -e ip.src -E headery -E separator, send_lens.csv导出之后文件里的每一行就是一个发送包的长度值后面想怎么算都行。4.2 用脚本算平均数与分位数导出的长度列表最直接的统计方式是用一个小脚本。我日常习惯用Python处理脚本不长但能一次性统计包数、平均值、最小值、最大值以及几个关键分位数。import sys lengths [] for line in sys.stdin: line line.strip() if line: lengths.append(int(line)) total len(lengths) if total 0: print(no packets) sys.exit(0) lengths.sort() avg sum(lengths) / total print(fcount{total}) print(favg{avg:.1f}) print(fmin{lengths[0]}) print(fmax{lengths[-1]}) for p in [50, 90, 95, 99]: idx min(total - 1, int(total * p / 100)) print(fp{p}{lengths[idx]})使用方式很简单tshark -r send.pcapng -Y ip.src 192.168.1.23 -T fields -e frame.len | python3 stat_len.py脚本里我最关注的是P95和P99。平均数容易被极端值带偏而P99能告诉你“99%的发送包长度都不超过这个值”这对判断业务的上限特征和异常长尾很有用。比如平均长度1200字节看着一切正常但P99却到了3000字节那就说明确实存在超过MTU的异常大包得进一步排查是不是TSO或者巨型帧导致的。如果机器上没有Python用awk也能算出基础指标awk {sum$1; count; if($1max || count1) max$1} END {print count count, avg sum/count, max max} send_lens.txt4.3 数据量太大时怎么抽样与分批统计抓包文件太大时图形界面打开会卡顿TShark全量统计也可能卡在导出环节。我遇到过好几个GB的pcap直接执行上面那条导出命令跑了很久也没有反应。这种情况下要分两步走。第一步用capinfos看一下文件概况确认包总量和大概的时间范围capinfos send.pcapng第二步用editcap把大文件切成多个小文件再分别处理。-c按包数切分-t按时间切分比如每10万个包切一个文件editcap -c 100000 send.pcapng send_part.pcapng切完之后可以写个for循环批量跑导出和统计最后合并结果。这样既不会卡死也能保证统计结果可复现。5. 实操案例一次HTTP上传的发送包长统计5.1 抓包准备与数据采集之前帮一个团队排查过上传慢的问题正好拿来做完整案例。业务背景是一个客户端要上传一个5MB左右的图片到服务器用户反馈耗时明显异常。抓包前先确认了客户端的本机IP假设是192.168.1.23然后选择客户端连外网用的网卡接口开始抓包。抓包期间让用户完整执行了一次上传操作总时长大约3秒。抓包结束后停止保存为upload.pcapng。在Wireshark里先输入显示过滤器ip.src 192.168.1.23整个分析过程都基于这个发送方向过滤。对于这种“只统计本机发出去的包”的需求这个条件从抓包到统计贯穿始终。5.2 看分布、画曲线、算分位数第一步打开Capture File Properties查看过滤后的发送包总情况。发送方向总包数大概3400个总字节数大约4.9MB平均包长接近1450字节。这个平均包长一下子就说明问题了客户端发出的包几乎都是满载大包应用层组包没有问题。第二步打开Packet Lengths表1280到2559区间的包占比超过95%40到79区间只有极少量。这说明发送方向几乎没有零碎的纯ACK小包干扰所有ACK都合并到了数据包里TCP传输效率非常高是典型的满载上行。第三步用IO Graph看了一下约3秒时间内的发送行为。发送字节曲线在前2.5秒内保持高位最后0.5秒跌到接近0符合一个完整文件上传的特征。发送包速率曲线和字节曲线高度一致没有出现包速率暴涨、字节速率不涨的反常情况。第四步用TShark导出frame.len统计分位数。命令是tshark -r upload.pcapng -Y ip.src 192.168.1.23 -T fields -e frame.len | python3 stat_len.py结果里P99是1514说明99%的发送包都在正常MTU范围内没有异常巨型包。5.3 从统计结果反向推断问题这个案例最后定位的结论是客户端发送方向不存在组包问题瓶颈在下行或服务端。为了验证我顺手统计了接收方向的包长分布发现接收方向大量是60字节左右的ACK包以及少量大包。也就是说该客户端上行满负荷发送下行确认也很正常因此问题大概率出在服务端处理耗时或者上公网链路的某些节点上。这里要强调一点统计发送包长并不仅仅是为了证明“客户端没问题”而是为了把问题范围收窄。有了这些长度分布数据你就有底气告诉对方客户端发的已经是满载大包了别再让我优化组包逻辑。6. 统计过程中最容易踩的坑6.1 TSO/GRO会让统计出现超长“假包”这个坑最隐蔽也最影响统计结果。现代网卡支持TSOTCP分段卸载和GRO接收聚合用户态发包时上层协议栈可以把很大的数据段直接交给网卡由网卡硬件自己拆成MTU大小的帧。问题在于抓包程序抓到的数据可能是在驱动层之后、硬件切分之前的形态于是Wireshark里会出现长度远超1514字节的“帧”比如一次抓到65535字节的包。如果统计发送包长时遇到平均长度暴涨、P99超过几千字节第一个要排查的就是TSO/GRO干扰。拿掉这个干扰最直接的办法是临时关闭网卡的TCP offload相关功能在Windows上是网卡属性里关掉“Large Send Offload”在Linux上可以用ethtool操作。但轮询业务不建议一直关闭offload这会增加CPU负载、降低吞吐一般只是排查期间临时关闭。还有一种折中方案是保留offload但在统计时跳过超过某个阈值的包并注明统计口径。6.2 方向过滤器写错导致收发混在一起前面提过ip.addr 本机IP会导致收发混合。这个坑出现的频率比想象中高尤其在多人协作时同事给你一个pcap让你统计你不清楚本机IP偷懒写了ip.addr 192.168.1.23最终统计结果自然对不上。更麻烦的是本机有多个IP的情况。比如有线网卡和无线网卡同时开启应用实际走的无线网卡的IP而你却拿有线网卡的IP去过滤结果可能是0个包。遇到这种情况先不急着过滤直接在Wireshark里打开Conversations或Endpoints从IP列表里确认本机发起流量的源IP是哪一个再写过滤条件。6.3 载荷为0的ACK包也在长度统计里TCP会话里接收方会发送不带业务数据的纯ACK包这些包在tcp.len字段里是0但在frame.len字段里仍然有60字节左右的长度。如果统计“应用实际发出的数据量”这堆纯ACK会虚增包数并把平均包长拉低。处理办法是分两种需求。如果只是想看所有发送帧的情况保留纯ACK没问题如果想统计实际载荷传输情况就要在过滤条件里加一个tcp.len 0。这条规则尤其适用于统计上传吞吐的场景否则包数看着很多实际有效载荷却要打折扣。6.4 包截断设置让所有统计长度都偏小抓包时Wireshark有个选项叫“Limit each packet to”允许只抓取每个包的前N个字节。默认一般不勾选但有些设备抓包或者为了省磁盘空间会设置成64字节或128字节。问题在于一旦开了截断pcap文件里的frame.len字段记录的就是截断后的实际长度而不是原始包长。这时候统计结果会出现整体偏小、大包全部消失的诡异现象。排查方法很简单抓包前检查Capture Options里有没有勾选截断选项拿到别人的pcap时打开任意一个大包看Packet Bytes面板底部是完整数据还是只有开头一段。如果是截断文件任何基于frame.len的统计都不足为信必须重新抓包。另外如果打开某个pcap文件时提示“在网络数据包负载中指定的长度与读取的字节数不匹配”通常也是文件不完整或写入异常比如抓包过程磁盘满、文件被截断这种文件的统计结果同样要慎用。6.5 VLAN标签和巨型帧对长度口径的影响统计结果和外部的软件计数器对不上时先看两个口径差异VLAN标签和FCS校验序列。带VLAN标签的帧会在以太网头和IP头之间多出4字节frame.len比无标签时多4但ip.len不受影响。如果网络环境里有VLAN而你对外报“平均包长1514字节”实际抓包可能是1518字节别人拿这个数去和自己系统的统计对比就会差出一截。FCS校验序列是帧尾的4字节Wireshark默认不把它计入frame.len而一些硬件计数器会把它算进去。再加上以太网帧间间隙、前导码这些物理层开销软件统计和硬件统计有百分之几的偏差是正常现象。做对比测试时一定要先明确双方用的统计口径否则又得花时间排查一场。最后说一点我自己的习惯。统计包长这件事看着是Wireshark里点几下但真正难的是弄清楚统计口径。你在报告里写“平均包长是1450字节”别人问一句“是frame.len、ip.len还是tcp.len过滤的是发送方向还是双向”答不上来整个结论就不成立。所以我每次做这类统计都会顺手把过滤表达式、统计字段和抓包时间写进报告备注里。这个小习惯帮我避掉过很多次返工也方便过几个月回头看数据时能快速确认当时统计的到底是什么。
返回列表