ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Wireshark数据包长度统计:一眼看穿网络性能瓶颈

Wireshark数据包长度统计:一眼看穿网络性能瓶颈 客户反馈内网传大文件速度上不去我让他顺手在网卡上抓了20秒流量。文件拿回来我连数据包的Payload都没细看先打开Statistics菜单里的Packet Lengths扫了一眼长度分布问题就猜了个七八成——满屏全是54字节左右的纯ACK小包真正携带数据的大包少得可怜。这不是个例很多人学Wireshark一直执着于读懂每个字段反而忽略了统计这个最能直接出结论、最省时间的功能入口。这篇文章就专门聊数据包长度统计这件事怎么抓包、怎么用Wireshark把发送的数据包长度统计出来、统计结果又能怎么用于排障。适合两类人看一类是刚装好Wireshark、拿到抓包文件不知道怎么提炼结论的新手另一类是已经会基本过滤、但没怎么认真研究过Statistics菜单的进阶用户。核心就一个目标让你下次打开任何一个pcap文件能在一分钟内说出这条链路上到底在跑什么东西、跑得对不对。1. 为什么关心数据包长度从抓包到读包1.1 长度是数据包的第一张身份证在Wireshark的抓包列表里有一个默认就存在的Length列每一行数据包后面都会跟着一个数字。这个数字看着不起眼但它是这个包最直观的指纹。一个包是来握手的、来传数据的、还是来刷存在的长度值基本能直接告诉你。举个例子一个标准的TCP纯ACK包抓包里通常显示54字节左右一个从网卡发出的满尺寸数据包在MTU为1500的以太网上通常是1514字节一段最常见的G.711语音流里的RTP包固定就是214字节上下。这些数字不需要看协议树扫一眼就能辨识出来。所以数据包长度统计本质上是在回答三个问题链路上有多少个包这些包都多大大小分布是否合理这三个问题展开之后就能顺藤摸瓜找到很多网络故障的根因。1.2 一个完整的以太网帧到底由什么组成要理解长度先得知道Wireshark里那个Length数值是怎么算出来的。以太网帧在抓包里看到的结构大致是目的MAC地址6字节、源MAC地址6字节、类型字段2字节后面才是真正的网络层数据。也就是说Wireshark显示的frame.len默认等于14字节的以太网头部加上后面的IP包长度。正常情况下标准以太网的MTU是1500字节所以一个满帧的IP包最多1500字节加上14字节的以太网头Wireshark里看到的满帧就是1514字节。如果链路上带了VLAN标签会额外多4字节变成1518字节。如果开启了巨型帧Jumbo Frame帧长可以超过1514常见的能到9000字节——你抓到一个2090字节的包基本就是在巨型帧环境里或者某些网卡和交换机对帧长做了特殊放行。还需要区分两个容易混淆的字段frame.len是原始帧长度frame.cap_len是实际捕获到的长度。这两个值一旦不相等说明包被截断了后面第6节会详细说这个坑。1.3 不同长度区间对应的身份画像把抓包文件里的长度分布拉出来看每个区间都有比较典型的代表长度区间Wireshark显示值典型协议/场景说明54 ~ 66TCP控制包ACK、SYN、FIN不带数据或只带极少选项62 ~ 74TCP SYN握手包通常带MSS、窗口缩放、时间戳等选项70 ~ 90DNS查询、少量ICMP头部开销占比高100 ~ 300HTTP请求、TLS握手、业务小包常见于应用层控制交互210 ~ 220VoIP语音包G.711每20毫秒一个规律性极强1280 ~ 1514接近MTU的数据包大批量文件传输时占比高这个表是我平时判断流量的一个重要坐标。看到分布图我脑子里基本能浮现出这链路的业务画面如果一大半是54字节的小包说明控制类或无效流量太多如果几乎全是1514的大包那多半是文件下载、视频流这类大吞吐业务。2. 抓包实操拿到一份能说明问题的样本2.1 选对网卡别抓了个寂寞统计结果准不准第一步取决于抓包样本靠不靠谱。打开Wireshark先看一眼主界面的网卡列表。Windows上用ipconfig、Linux上用ip addr show先确认哪个网卡是真正承载业务的。最容易犯的错是选了Loopback回环网卡结果抓到一堆空包或者干脆选了虚拟网卡业务流量根本不走那里。如果你要抓的是访问外网的流量就选有公网地址或走默认网关的那块物理网卡抓内网服务器之间的流量选接内网的那块网卡。还有一个细节默认情况下Wireshark会打开混杂模式Promiscuous Mode也就是网卡不只收目标为自己MAC地址的包而是把线路上能看到的包都收进来。这个选项一定要保持开启尤其你抓的是交换机镜像口或者Wi-Fi探针流量时关了它可能什么都抓不到。2.2 抓包选项里最容易埋雷的snaplen点工具栏的齿轮图标进入Capture Options里面有一个Limit each packet to选项这就是snaplen抓包截断长度设置。Wireshark默认是65535字节基本等于不限制因为正常以太网帧最大也就9000多字节。但如果你把这里改成了520就会出现一个很经典的怪现象每个包都只抓到前520字节后面的内容全部丢失。Wireshark会在Info列提示Packet size limited during capture协议树里很多字段解析不出来一长串数据全变成了Data的残缺内容。后面第6节我会专门讲怎么排查和修复。这里顺便说个原则做长度统计之前先确认snaplen没有被改小。否则你统计出来的分布是被截断过的尤其大包会集体缩水看起来全是小额数据包容易误判。2.3 用显示过滤器把目标流量剥出来抓包全程可以在Capture Options里设置抓包过滤器Capture Filter语法是BPF那套比如host 192.168.1.100 and tcp port 443只保留和某个IP的443端口相关的包。这种过滤器在抓包阶段就丢弃不关心的流量能大幅减小文件体积。但抓包过滤器有个局限它不认识frame.len这种Wireshark上层字段。真要按长度统计和过滤得用抓完之后的显示过滤器Display Filter。比如frame.len 1400只看大包frame.len 80只看小包tcp.len 0只看TCP里真正带数据的包tcp.len 0只看TCP纯ACK这类无载荷包frame.cap_len frame.len直接找出被截断的包记住这个区别很关键。很多人拿着frame.len 1400往抓包过滤器里填结果报错就是因为用错了地方。2.4 实操完整抓取一次文件下载我以最常见的HTTP大文件下载为例走一遍标准流程先确认网卡记录本机IP比如192.168.1.100打开Capture Options选择正确的网卡把snaplen保持在65535为了减少干扰可以加一条抓包过滤器host 192.168.1.100只看和本机相关的流量点击Start开始抓包用curl或浏览器请求一个大文件比如curl -o /dev/null http://example.com/large-file.bin下载结束后停止抓包保存为download.pcapng。这份文件里就包含了TCP三次握手、HTTP请求、大量1514字节的数据包、以及回程的ACK小包。用它来做长度统计正好能看到一个典型下载业务的全貌从握手小包到请求小包再到满负荷数据大包最后到结束断开的小包。3. 用Wireshark自带统计功能看长度分布3.1 Statistics Packet Lengths 逐个区间读懂对刚保存的download.pcapng打开Statistics菜单点击Packet Lengths会弹出按长度区间统计的表格。Wireshark自动把长度分成类似40到79、80到159、160到319、320到639、640到1279、1280到2559这样翻倍的区间每行显示包数和占比。这份数据是最直接的结论来源。一次典型的HTTP大文件下载分布大概长这样长度区间包数占比可能的角色40 ~ 79185030%三次握手、纯ACK回包80 ~ 1591202%HTTP请求、TLS握手160 ~ 319601%个别控制包640 ~ 12793505.6%中尺寸数据块1280 ~ 2559380061%接近MTU的数据包看到这个分布脑子里就能浮现画面一半以上的包是满尺寸数据包说明发送方在努力用大块数据填充链路三成是ACK是因为接收方每收到一批数据都要确认整体大包占比越高链路利用率通常越高。这个对话框底部有Copy按钮可以直接把统计表格复制成CSV方便贴进汇报文档或者Excel里二次加工。3.2 结合过滤器做定向统计只看发送方向很多时候我们不关心全部流量只想统计某个IP发送的数据包长度。做法很简单在显示过滤器里填ip.src 192.168.1.100然后再打开Packet Lengths此时统计的就是从这个IP发出去的所有包。如果想再进一步只统计这个IP发送且真正携带TCP数据的包过滤条件改成ip.src 192.168.1.100 and tcp.len 0。这组数据才是真正体现发送吞吐能力的指标。比如一个服务器IP如果它发出的包里90%都是纯ACK说明它一直在被动响应别人本身没有多少数据要传。这里分享一个顺手的小技巧在Packet Lengths对话框打开的状态下直接改显示过滤器对话框里的数据会实时刷新不用来回开关。我排障时经常把过滤器和统计窗口并排操作效率高很多。3.3 Conversations与Endpoints谁在发大包谁在发小包Packet Lengths看的是全局分布如果要细化到哪台主机、哪对连接在发什么长度的包就要看Statistics里的Conversations和Endpoints。Endpoints会按IP或MAC地址汇总每个端点的发包数、收包数、发送字节数、接收字节数。比如你先发现整个抓包里某个IP的发送字节数是别人的100倍那基本确认它就是流量大户。点一下Bytes列排序谁是罪魁祸首一目了然。Conversations则按通信双方IP加端口维度做汇总能看到一条TCP连接的包数和字节数。比如下载任务里服务器和客户端之间的那条连接字节数会高得吓人如果是某个后台服务在疯狂轮询那连接数量虽多但每条连接的字节数都很小。做长度统计时先用Conversations锁定可疑连接再右键选择Apply as Filter就能只看这条连接的包然后回到Packet Lengths看它的长度分布。3.4 IO Graph长度变化趋势一眼看穿Packet Lengths是一张静态快照IO Graph则能看到时间维度的变化。打开Statistics IO Graph默认横轴是时间纵轴是包速率。这里有两个很有价值的玩法。第一个玩法把Y轴单位从Packets改成Bytes立刻能看出某个时间段内的字节吞吐。如果曲线在某个时间点突然断崖式下跌结合前后的包长度分布能判断是数据包变小了还是包数量变少了两种情况的排障方向完全不同。第二个玩法添加两条额外的图形线一条的过滤条件填frame.len 1400另一条填frame.len 80。这样一条线代表大包流量另一条代表小包流量。当两条线出现背离时比如大包线往下掉、小包线反而往上窜基本可以断定是出现了大量ACK或重传这类控制流量业务数据却在饿肚子。4. 更精细的统计tshark与自定义列4.1 什么时候需要离开图形界面Wireshark图形界面很直观但有两个场景它会显得笨重一是PCAP文件非常多几十个文件挨个点Statistics菜单能点到手酸二是服务器上根本没有图形环境只有tshark命令行工具可以用。tshark是Wireshark自带的命令行版本装Wireshark的时候会一起装好。它能对PCAP做批处理统计还能写出带精确条件的过滤逻辑非常适合沉淀成脚本定期跑。我的习惯是手工排障用图形界面批量复盘和例行巡检用tshark。4.2 tshark统计长度的几组高频命令有一组我几乎每天要用的命令建议抄进自己的笔记# 列出每个包的编号和长度 tshark -r download.pcapng -T fields -e frame.number -e frame.len # 按长度聚合统计得出每种长度的包数量 tshark -r download.pcapng -T fields -e frame.len | sort | uniq -c | sort -rn | head -20 # 统计长度大于1400字节的数据包个数 tshark -r download.pcapng -Y frame.len 1400 | wc -l # 查看最大的包长度 tshark -r download.pcapng -T fields -e frame.len | sort -n | tail -1在Windows上的cmd环境里没有wc命令可以用find /c /v 代替tshark -r download.pcapng -Y frame.len 1400 | find /c /v 。PowerShell里更简单(tshark -r download.pcapng -Y frame.len 1400).Count直接拿数组长度。这些命令组合起来就能在几秒钟内产出一份长度统计报告。比如我把第二条命令的输出重定向到文本文件再配合awk或者Excel几分钟就能把几百个PCAP的统计结果汇总成一张总表这活儿放图形界面里做至少折腾一上午。4.3 自定义显示列让长度值自己说话除了统计面板我还推荐把常用长度字段直接做成列表列这样抓包文件一打开长度相关的信息就摆在眼前连过滤器都不用输。操作很简单在抓包列表的列标题区点右键选Column Preferences点左下角的加号新增一列字段名填frame.len标题写成帧长默认就有但我会额外加一列frame.cap_len用来对照有没有截断。再加一列tcp.len就能一眼区分纯ACK和数据包。有了这三列扫一眼列表就能快速识别tcp.len为0的包多半是控制包tcp.len接近1460或1448的是满载荷数据包。要统计某个方向的数据包长度甚至可以直接在列表里数。4.4 统计某个IP发出的包长度分布完整示例假设我要分析192.168.1.100这个IP对外发送流量的大小特征用一条命令就能出结果tshark -r capture.pcapng -Y ip.src 192.168.1.100 -T fields -e frame.len | sort | uniq -c | sort -rn输出大概长这样3420 54 1890 1514 320 66 180 256 80 1207看到这个结果我会立刻意识到3420个54字节包说明这个IP发出去大量纯ACK1890个1514字节满帧说明它也在积极发送数据。如果这个IP是文件服务器这个比例算健康如果它是一个Web应用服务器而54字节包占大头那就要查应用是不是频繁建立连接、频繁丢小请求导致大量确认包往返。5. 从长度统计反推网络问题5.1 案例一MTU/MSS异常排查有一次用户反馈跨网段传文件经常卡住我看了抓包统计发现数据包最大长度只有576字节。这个数字很经典——它是很多老协议和隧道场景下的兜底MTU值。进一步看所有超过576字节的IP包都被分片了。这说明链路上某个环节的MTU比1500小而中间设备可能在静默丢弃超过自身MTU的数据包导致TCP探测不到真实MTU只能靠分片或者降速来苟着。这种情况下长度分布里大包占比会明显偏低碎片化的小包占比升高。排查方向就变成找出路径上MTU最小的设备检查隧道封装是否有额外开销确认两端网卡的MSS clamp配置。5.2 案例二小包风暴开头说的那个客户案例就是典型的小包风暴。我统计完发现20秒抓包里一共有约20万个包但其中超过1400字节的包只有5000个剩下的几乎全是54到66字节的ACK和探测包。平均包长不到100字节链路看起来包很多、很忙实际吞吐不到几Mbps。这种场景通常不是带宽不够而是应用层设计有问题比如客户端不断发小查询请求服务器处理完立刻回ACK但迟迟不发真正的业务数据或者某个协议实现了很短的保活机制每分钟发几十个探活包。应对方法分两层网络层可以适当关注交换机CPU应用层则要优化交互频率、合并请求、开启批量数据推送把小包的数量降下来。5.3 案例三分片与异常大帧长度统计还有一个容易被忽视的作用就是快速发现分片和巨型帧问题。如果你看到大量IP包的长度不是1514或者正常数据包尺寸而是出现一堆900、1480这类半截尺寸并且分片信息里有很多Fragmented IP protocol标志说明路径上的MTU和发送端不一致。还有一种情况是我实际遇到过的某台服务器网卡开了巨型帧MTU 9000但同网段交换机和另一端网卡没开。抓包里会出现超过1514字节的帧比如2090字节或者更大但这些帧过不了没开巨型帧的设备导致丢包和重传。这种问题用Packet Lengths一眼就能识别正常应该是1514封顶结果冒出一堆3000、5000字节的包那MTU配置肯定不统一。5.4 案例四协议开销计算长度统计还能用来做链路容量规划。比如一段G.711语音每20毫秒一个RTP包帧长214字节每秒50个包单向速率就是214乘以50乘以8约等于85.6kbps。再加上RTCP等控制流量一路语音通话大概占90kbps上下。当你从抓包长度统计里看到大量214字节左右的规律包时就可以反推线路正在承载多少路语音。同样的算法可以套到任何业务上用Packet Lengths算平均包长再乘以每秒包数就是这条流的实际带宽占用。我在写网络扩容方案时经常用这组数据比直接拍脑袋估带宽靠谱得多。6. 常见问题与避坑实录6.1 为什么只显示520字节这是被问得最多的一个问题。现象是抓包列表里很多包的Length列显示520点开详情数据内容到520字节就没了Info列还带着Packet size limited during capture的提示。原因几乎都是抓包时把snaplen设成了520。具体位置就是Capture Options里的Limit each packet to输入框。有人为了省磁盘空间把值调小结果把完整的包截了肢也有人是自己没注意输入法手滑填了个520进去。要确认一个已有的抓包文件是否被截断用显示过滤器frame.cap_len frame.len查一下或者直接看Info列的提示。请注意截断是捕获阶段就发生的已经保存的文件救不回来唯一的办法是重新抓包把snaplen改回65535。6.2 怎样抓出2090字节的完整数据如果确实需要看到2090字节甚至更长的完整包分三步走第一在Capture Options里把snaplen改成65535或者取消Limit each packet to的勾选确保不会截断 第二确认整条链路上的网卡和交换机都允许这个帧长通过。普通的1500字节MTU根本不会有2090字节的帧能出现这种帧说明某些设备已经开启巨型帧 第三抓包完成后在包列表里点中目标包右侧详情面板展开最底层的Data字段就能看到完整载荷。如果嫌麻烦直接在包上右键选Follow TCP StreamWireshark会帮你把TCP流重组好原始字节一个不落。另外有个细节个别网卡驱动在抓到巨型帧时可能会丢包或者截断到1514字节这种属于硬件限制需要确认网卡属性里是否启用了Jumbo Packet选项并设置成匹配的MTU值。6.3 长时间抓包的正确姿势做长度统计有时候需要抓几小时甚至一整天的流量。这时候直接开着Wireshark抓文件会膨胀到几十GB统计界面也会卡成幻灯片。我建议用环形缓冲。在Capture Options里勾选Use multiple files设置Next file every按时间或大小分片比如每100MB切一个文件再勾选Use ring buffer with N files比如填10这样最多保留最近10个文件老文件自动覆盖磁盘永远不会爆。命令行版本对应是tshark -i eth0 -b filesize:102400 -b files:10 -w long_capture.pcapngfilesize单位是KB102400就是100MB。长时间抓包结束后的统计也要注意不要直接对10个文件分别开Packet Lengths手动加总正确做法是用tshark批量处理for f in long_capture_*.pcapng; do tshark -r $f -T fields -e frame.len done | sort | uniq -c | sort -rn | head -20这样能把所有分片文件合并算出一个总分布避免手工汇总出错。6.4 还有几个容易误判的细节最后提醒几个实战中经常踩的坑。第一个是校验和报错。抓包时如果看到大量TCP checksum incorrect先别急着判定网络损坏。很多网卡驱动开启了校验和卸载Checksum Offload发出的包在校验和字段填的是占位值真正的校验和由网卡硬件在发送瞬间计算。这种情况在抓包里表现为发出方向包校验和错误实际网络上并没有问题。要准确检查可以临时关掉网卡的TCP/IP校验和卸载功能再抓一次。第二个是混杂模式。前面提过它默认开启但有些抓包场景比如Windows的无线网卡即使开了混杂模式也抓不到其他设备的帧这是驱动限制不是统计逻辑出错。第三个是抓包过滤器里不能直接写frame.len。抓包过滤器用的是BPF语法只认识长度相关的原始字段比如less 1000表示抓小于1000字节的包greater 1400表示抓大于1400字节的包。这个概念和显示过滤器完全不同混用最容易报错。第四个是统计口径。同一个PCAP文件用Packet Lengths统计的包数和用tshark的-Y frame.len...统计的结果必须一致如果对不上多半是你没注意truncated包的frame.len和frame.cap_len差异或者混用了不同版本的过滤器语法。我一般在关键结论出来前会先用tshark交叉验证一遍。最后分享一个我自己的习惯我电脑上长期放着一个叫pktstat.sh的脚本里面就是第4节那几行tshark命令每次拿到PCAP先跑一遍输出保存成文本再打开Wireshark看细节。这样的好处是统计结论有据可查、可复现也方便后期做对比。数据包长度这个指标看起来简单但它就像测量一个人体温——不测不知道测了之后很多隐藏问题都会自己浮出来。建议你下次抓完包先别急着翻协议树点开Packet Lengths让数字先开口说话。
返回列表