抓包这事儿,听起来像是老网工才会的活儿,但只要你做过一次移动端接口调试,或者被某个"只在线上环境出现"的Bug逼疯过,就会明白:能亲手看到客户端到底发了什么、服务器到底回了什么,是排障效率的分水岭。
我这些年用过的抓包工具不算少,从最早在Windows上点开Fiddler,到后来换Mac以后常驻菜单栏的Charles,再到排查TCP层问题必须拉出来的Wireshark,最近又因为要做流量归档试了试Proxyman和TraceEagle。说实话,没有任何一款工具能通吃所有场景,每款工具的设计出发点完全不同,选错了工具,轻则多花半天时间,重则连问题都复现不了。这篇就把我实际使用中的横向对比和踩坑记录整理出来,给打算入坑或者正在工具选型的同学做个参考。
1. 抓包不是过时技能:调试链路里的"最后一公里"
很多开发者的习惯是先在代码里打日志,出了问题看日志、看监控、看APM,实在不行再让运维帮忙抓一下。这个流程没错,但它有一个很大的盲区:客户端发出请求到服务端收到请求之间,中间还有代理、网关、DNS、负载均衡、WAF、HTTPS握手等环节,任何一环出了问题,服务端日志根本看不到完整信息,客户端的日志也只会记录到"请求失败"或"超时"这种无意义的结果。
抓包工具解决的正是这个问题——它在链路中间开一个"观察窗",让你直接看到网卡上或者代理层经过的原始流量。我曾经排查过一个非常诡异的线上问题:用户反馈App部分图片加载不出来,但日志里没有任何报错,网络监控也正常。后来用Wireshark抓了Wi-Fi网卡上的流量才发现,某些HTTPS请求被网关改了MSS值,导致TCP握手后的大包被丢弃,小包能通,大包全丢。这种问题,你靠打日志打一辈子都发现不了。
所以说,抓包不是排障的"最后手段",而是应该前置到日常开发调试里的基本技能。而在选工具之前,得先搞明白一件事:你需要的到底是"代理层抓包"还是"链路层抓包"。这两者的工作方式完全不同,后续所有工具选择的逻辑都从这一点延伸出来。
代理层抓包工具(Charles、Fiddler、Proxyman)通过把自己注册为HTTP/HTTPS代理,让客户端把流量主动交给它,再由它转发给目标服务器。它的优势是能直接解密HTTPS、能看到请求头和响应体、能做断点和Mock,适合调试业务接口。
链路层抓包工具(Wireshark则是典型代表)则直接监听物理网卡或虚拟网卡上的所有数据包,客户端根本感知不到它的存在。它能看到TCP三次握手、TLS握手细节、DNS查询、TCP重传,甚至能抓到非HTTP协议(比如数据库协议、MQTT、私有协议)的通信内容,适合排查网络底层问题。
理解了这一层区别,再看下面几款工具的对比,思路会清晰很多。
2. 五款工具的核心差异:先看方向,再谈功能
2.1 一张表看透五款工具的定位
先说结论:Charles、Fiddler、Proxyman都是代理类工具,它们解决的是同一个问题——"看HTTP/HTTPS请求的内容",区别在于生态、平台和操作体验;Wireshark是协议分析类工具,解决的是"看网络链路上到底发生了什么";TraceEagle算是后起之秀,更像是一个面向"流量取证和团队协作"的流量分析平台。
下面的表格是我根据自己的实际使用情况整理的,不涉及官方宣传参数,只谈体感:
| 工具 | 核心定位 | 主要平台 | 上手难度 | HTTPS解密 | 移动端支持 | 自动化能力 | 我最常用的场景 |
|---|---|---|---|---|---|---|---|
| Charles | 代理调试 | macOS / Windows | 中 | 需要手动信任证书 | 强,iOS/Android都方便 | 支持Repeat、Map、Rewrite | 移动端App接口调试、Mock数据 |
| Fiddler Classic | 代理调试 | Windows | 中 | 需要手动信任证书 | 强,配置略繁琐 | 强,支持脚本扩展 | Windows下的HTTP/HTTPS调试、弱网模拟 |
| Proxyman | 代理调试 | macOS / iOS | 低 | 界面引导非常友好 | 极强,尤其iOS生态 | 支持JavaScript脚本 | macOS + iPhone 组合调试 |
| Wireshark | 链路协议分析 | 全平台 | 高 | 需要配置TLS密钥,不支持实时解密 | 需要配合远程抓包或Android tcpdump | 支持tshark命令行 | TCP/IP协议问题、底层网络排障 |
| TraceEagle | 流量分析与协查 | 全平台(Web端为主) | 中 | 支持导入抓包文件分析 | 弱,一般不直接抓取移动端 | 支持规则引擎/报告导出 | 导出报告、团队协作、多文件流量比 |
2.2 选型的第一原则:不要因为别人说好用就换工具
我在不少技术群里看到过这种对话:"求推荐一个好用的抓包工具",下面立刻有人回"Proxyman,比Charles好用一百倍",然后又有人回"Fiddler才是永远的神"。这种讨论其实没有意义,因为提问的人没有说清楚自己的场景。
如果你是Windows用户,不碰Mac,那Proxyman的优势就跟你没什么关系;如果你要抓的是局域网里某个嵌入式设备发的私有协议包,那Charles和Fiddler根本派不上用场;如果你只是想看某个网站返回的JSON结构,杀鸡用牛刀上Wireshark,只会把自己绕晕在TCP报文里。
所以,选型的第一步是确认自己的核心场景是"业务协议调试"还是"网络链路分析"。业务调试优先选代理类工具,链路分析优先选Wireshark。至于代理类工具内部怎么选,下面几节我会展开讲各自的细节和坑。
3. Charles:手机抓包绕不开的坎,以及证书信任的全套解法
3.1 最简配置:电脑+手机怎么连通
Charles在移动端调试界的地位,类似于Photoshop在平面设计界的地位——不一定是最好用的,但一定是大家默认的基准线。它默认监听8888端口,抓包前要做的事情很简单:电脑和手机连同一个Wi-Fi,手机Wi-Fi代理手动设置为"电脑IP:8888",然后电脑上Charles会弹出一个提示框问你是否允许该设备的连接,点Allow就可以了。
但这里有个非常容易踩的坑:电脑IP一定要填局域网IP,不是127.0.0.1。很多人第一反应会填本机回环地址,结果手机当然连不上。我建议直接在Charles的Help -> Local IP Address里查看当前电脑的局域网IP,复制过去最稳妥。
另外,如果你的电脑开了防火墙,记得放行TCP 8888端口。Windows上比较常见,macOS一般不会有这个拦截弹窗。
连上之后,如果只抓HTTP流量,到此就结束了。但要抓HTTPS,还有一套证书要处理。
3.2 抓不到包的四个高频原因
很多人的HTTPS抓包卡在证书环节。Charles的官方地址是chls.pro/ssl,手机浏览器访问这个地址下载证书,但下载之后不是立刻就生效的,尤其是iOS设备,还需要去"设置 -> 通用 -> 关于本机 -> 证书信任设置"里把Charles的证书开关打开。这一步漏掉,Charles会看到一堆乱码或者直接显示"Handshake Failed"。
整个配置流程里,我整理了几个高频踩坑点:
第一,SSL代理没有开启。Charles默认不会解密HTTPS流量,必须在菜单Proxy -> SSL Proxying Settings里勾选Enable SSL Proxying,并且在Location列表里添加Host为"*"、Port为443的规则。如果不加这个规则,Charles只能看到CONNECT请求和加密后的乱码,看不到具体内容。
第二,域名匹配问题。有些App内部会请求很多子域名,比如api.example.com、static.example.com、img.example.com,如果只给api.example.com配置了SSL代理,其他域名仍然看不到内容。所以调试阶段图省事的话,直接填"*"匹配所有域名,先跑通,再收窄范围。
第三,Android 7以上系统的用户证书信任问题。Android 7之后,系统默认不再信任用户安装的CA证书,所以很多App用Charles抓包会直接报SSL错误,甚至App直接断网。解决办法分两种:如果App的AndroidManifest里配置了networkSecurityConfig并信任用户证书,那直接安装就行;否则就需要root后把Charles证书装进系统证书目录,或者用Frida之类的框架绕过证书校验。
第四,App做了SSL Pinning(证书绑定)。这是最常见的抓不到包的原因。一些金融类、社交类App会在客户端内置服务端证书的公钥或证书指纹,请求时校验服务端证书是否匹配,Charles的证书自然校验不通过。遇到这种情况,Charles本身是解决不了的,需要配合其他手段,这不是工具的问题。
3.3 Mock数据:Charles真正值钱的地方
Charles除了看包,还有一个非常适合开发自测的功能:Map Local。
比如后端接口还没写好,但前端需要联调页面,你可以先用Charles在浏览器里跑一次正常请求,拿到真实返回的JSON,保存成一个本地文件。然后右键这个请求,选择Map Local,把请求映射到本地文件。之后每次发起该请求,Charles都会直接返回本地文件内容,不会再请求真实服务器。
这个功能我有一次帮了大忙:那是一个第三方支付的回调通知联调,测试环境没有真实支付渠道,我们要模拟各种回调状态(成功、失败、退款、重复通知)。我用Charles把回调URL分别Map到几个不同状态的JSON文件上,然后本地脚本轮询触发,几分钟就把整个状态机测完了。
Map Local配合Breakpoint使用效果更好。给某个请求设置断点后,请求发出去时Charles会拦下来,这时候可以手动修改请求参数、请求头、响应内容,再点击Execute放行。这套组合技在做异常分支测试的时候是真正的效率神器。
4. Fiddler:Windows老手的最爱,但卸载后会留坑
4.1 Fiddler Classic和Everywhere怎么选
Fiddler在Windows生态里的地位很稳固,因为它是.NET系的工具,微软技术栈的开发者用得最多。
需要先说明一点,Fiddler现在分两个版本:Fiddler Classic(经典版,免费)和Fiddler Everywhere(跨平台收费版)。Classic在Windows上功能依然够用,界面虽然老,但胜在轻量和稳定;Everywhere的界面现代化得多,支持macOS和Linux,但核心抓包逻辑和Classic没什么质的区别。
我的建议是:如果你只是Windows本地调试,不需要团队协作,直接用Fiddler Classic就够了。如果想要更好的界面、需要在多平台之间切换、或者需要和团队成员共享抓包会话,再考虑Everywhere。Classic的免费版有一些高级功能(比如AutoResponder、弱网模拟)并没有被阉割,用来做普通接口调试和Mock完全没问题。
有一点要吐槽:Fiddler Classic没有官方中文,所以网上很多文章会建议你下载汉化版。但我不太推荐用第三方汉化版本,因为这些汉化版经常在安装的时候捆绑其他软件,而且汉化不完整,容易出乱码。如果你英文看不太习惯,建议就用原版,固定记几个常用菜单位置就行,Fiddler的操作逻辑非常固定,用熟了根本不需要看菜单文字。
4.2 卸载后上不了网的根因与修复
Fiddler有一个出名的"后遗症",就是卸载之后电脑上不了网。我在热搜词里也看到了"fiddler卸载后上不了网",这个问题其实非常经典,根因在于Fiddler在运行时会修改Windows的系统代理设置。
Windows的HTTP代理配置存在注册表项"HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings"里,Fiddler启动时会把ProxyEnable设为1,并把代理服务器指向127.0.0.1:8888。正常退出时它会还原,但如果Fiddler崩溃、被任务管理器强杀、或者电脑直接断电,代理配置就没有被还原。卸载程序也经常只删软件文件,不清理注册表代理项,于是系统代理还指向已经失效的本地端口,所有浏览器请求都走一个不存在的代理,自然就上不了网了。
修复方法很简单,不需要重装系统:
按Win+R输入inetcpl.cpl打开Internet选项,切到"连接"选项卡,点"局域网设置",把"为LAN使用代理服务器"的勾选去掉,确定保存。或者在Windows设置的"网络和Internet"->"代理"页面里,把"使用代理服务器"开关关掉。
这里有个我自己的经验:判断是不是代理残留,不用打开注册表编辑器,只需要打开命令行执行reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable,如果返回的数值是0x1,那就是有残留。如果不想敲命令,看"局域网设置"对话框里的代理服务器地址是否是127.0.0.1:8888或者某个你不认识的端口,基本也能确认。
我在团队里碰到过不止一个同事遇到这个问题,根本原因都是Fiddler非正常退出。所以用Fiddler有个小习惯要养成:关电脑前,先把Fiddler正常退出,再从托盘区确认它已经关闭,不然下次开机可能会莫名其妙"没网"。
4.3 弱网模拟和脚本扩展
Fiddler在弱网测试方面做得非常方便。菜单Rules -> Performance -> Simulate Modem Speeds,一键就模拟出拨号网络的延迟和速度。如果想自定义参数,还得去ScriptEditor里改,Fiddler的脚本是C#语法,开发者改起来没什么门槛。
我试过在脚本里把网络延迟设成1000ms、丢包率设成30%,用来测试一个上传图片功能在极差网络下的表现。结果还真发现了一个问题:上传请求在弱网下重复发起时,客户端会在收到响应前就超时关闭连接,导致服务端明明处理成功了,客户端却提示失败。这个问题用Fiddler的弱网模拟一复现,后端加了个幂等逻辑就解决了。
Fiddler的脚本能力比Charles强不少,你可以在OnBeforeRequest里改请求头、加参数、做随机化,甚至把一套测试流程写成自动化脚本直接跑。在Windows环境做接口自动化测试,Fiddler的脚本体系是很值得投入时间去研究的。
5. Wireshark:协议分析的正确打开方式
5.1 网卡层抓包和代理层抓包的本质区别
Wireshark和前面几款工具完全不是一个世界的产物。它运行在网卡层面,直接采集链路上经过的数据帧,不需要客户端配置任何代理,也不需要安装证书,它就静静地看着所有流量通过。
很多人第一次打开Wireshark会懵,因为界面上全是看不懂的包列表:Ethernet帧头、IP头、TCP头、TLS记录。这很正常,Wireshark的目标用户本来就是网络工程师和安全工程师,它的信息密度是最高的,但学习曲线也最陡。
举个例子,用Charles抓包,你看到的是"GET /api/user HTTP/1.1"这样一个完整的请求,用Wireshark抓包,你会看到这个GET请求被拆成了好几个TCP分段,每个分段带着序号、确认号、窗口大小等信息。Wireshark看的是"传输过程",不是"请求内容"。
所以我的建议很直接:不要试图用Wireshark替代Charles/Fiddler做日常接口调试,但当你遇到TCP层丢包、连接被重置、TLS握手失败、DNS解析异常这类代理工具完全没法解释的问题时,Wireshark是唯一能看清真相的工具。
5.2 筛选器、流重组和TLS解密
Wireshark最有价值的能力是过滤器和流重组。
过滤器分两种:抓包过滤器(Capture Filter)和显示过滤器(Display Filter)。前者在抓包开始前设置,只抓满足条件的包;后者在抓包完成后设置,从已抓到的包里筛选显示。日常用显示过滤器足够,常用的几个语法我到现在还在用:
ip.addr == 192.168.1.100只看某个IP的通信tcp.port == 443只看443端口的流量http.request只看HTTP请求tls.handshake.type == 1只看TLS ClientHello包tcp.analysis.flags快速定位TCP异常报文(重传、乱序、零窗口等)
流重组(Follow Stream)是看完整会话的关键。在TCP包上右键 -> Follow -> TCP Stream,Wireshark会把这次TCP连接里的所有分段重新拼成完整的字节流,HTTP请求头、请求体、响应体一目了然。如果是HTTP/2流量,选Follow HTTP/2 Stream。
TLS解密稍微麻烦一点,需要让目标浏览器或应用把会话密钥导出到本地文件。Chrome和Firefox都可以通过环境变量SSLKEYLOGFILE来记录密钥。设置好之后,在Wireshark的Preferences -> Protocols -> TLS里把密钥文件填进去,就能看到解密后的HTTPS明文内容。这个方法只适用于你能控制客户端环境的场景,比如用浏览器调试自己的服务,对于App里的流量解密,依然需要借助代理工具。
5.3 为什么只看到520字节,完整的2090字节去哪了
我注意到搜索热词里有一个很典型的问题:"Wireshark为何只能显示520字节数据,怎么显示2090个字节数据"。这个问题正好能解释清楚Wireshark的数据显示逻辑。
首先要明确一个概念:Wireshark包列表里的"Length"列,显示的是单个数据帧的长度。一个2000多字节的HTTP响应,在网络层会被拆成多个TCP分段,每个分段是一个独立的数据帧。正常情况下,以太网MTU是1500字节,减去IP头和TCP头的开销,单个TCP分段最多能携带1460字节的payload。所以如果你在一个包列表里看到某个包只有520字节,并不代表数据只有520字节,而是说明这个响应被拆分成了多个包,你看到的520字节只是其中的一个分段。
想看完整数据,有两种方式:
第一,右键任意一个TCP包,选择"Follow TCP Stream",Wireshark会自动把属于同一条TCP连接的所有分段重组成完整的字节流,你就能看到完整的HTTP响应体,那2090字节就在这里。
第二,如果你只是想知道这条HTTP响应一共占了多少字节,不需要看内容,可以用Statistics -> Endpoints或Conversations,按端口聚合统计,看发送/接收字节数。
另外,还有一个细节可能导致"看起来只有520字节":Wireshark默认开启了Edit -> Preferences -> Appearance -> Columns里的多个列,里面有一个"Length"列,显示的是当前捕获帧的长度。但如果你的网卡开启了TSO(TCP Segmentation Offload)或 GRO(Generic Receive Offload),网卡会在硬件层面把多个TCP分段合并成一个大的"超级包"再交给系统,Wireshark这时就可能看到超过以太网MTU的帧长度,比如直接看到2090字节。这就是为什么有些人说"同事抓到2090字节,我为什么只看到520字节"——可能不是因为数据不一样,而是因为网卡卸载功能的状态不一样。
我建议在做底层抓包分析时,先把网卡的TSO/GRO关掉,具体方法是在系统网络设置里关闭"TCP/IP卸载"或"大发送卸载",这样才能看到真实的分段结构。不过如果你只是想看应用层内容,开不开其实都无所谓,Follow Stream才是正确路径。
6. Proxyman:macOS和iPhone调试的顺滑选择
6.1 从Charles迁移到Proxyman的体验
第一次用Proxyman是朋友推荐的,他说Charles在Apple Silicon上的表现太差了,菜单栏图标经常卡顿,大流量下界面还会掉帧。我半信半疑地下载了Proxyman,说实话,第一次抓到包的时候确实被它的界面和流畅度惊艳到了。
Proxyman的UI风格是典型的macOS原生设计语言,左侧树形结构的域名列表、中间请求列表、右侧详情面板,布局合理且响应迅速。它最贴心的一点是证书安装几乎全自动:打开App第一次抓HTTPS,它会自动检查系统是否已安装Proxyman证书,引导你装完证书后还会提醒你去"钥匙串访问"里把证书信任级别改成"始终信任"。这套流程比Charles的处理细致不少,Charles装证书时如果忘了改信任级别,真的有人会卡在那里半天。
还有一个我特别喜欢的细节:Proxyman自带对iOS模拟器的支持,只要在菜单里选择"iOS Simulator",它会自动把模拟器网络代理指到本机,连手机都不用掏出来,直接在模拟器里复现问题。
6.2 iOS真机与模拟器的抓包细节
Proxyman默认监听端口是9090,和Charles的8888不同,配置iPhone时需要留意。
真机抓包的操作和Charles类似:同一Wi-Fi下,手机Wi-Fi设置里把HTTP代理改为手动,服务器填Mac的局域网IP,端口填9090。抓HTTPS时,手机浏览器打开https://proxyman.io/cert或者直接访问Proxyman生成的证书地址下载证书,然后在iOS的"证书信任设置"里打开开关。
实际使用中,Proxyman对HTTP/2的支持比Charles好不少。现在iOS App普遍使用HTTP/2,Charles在处理HTTP/2流量时偶尔会出现乱序或者看不到响应头的情况,Proxyman在这方面的解析明显更准确,这可能是它在iOS开发者圈子里口碑不错的原因之一。
另外,Proxyman的脚本功能也很强,它用JavaScript写脚本,可以在请求发出前和响应返回后拦截修改。我写过一个小脚本,给某个App的所有请求自动追加一个签名header,省去了手动修改的重复劳动。这比Charles的Repeat和Rewrite操作灵活得多。
不过Proxyman也不是没有缺点。它的Windows版本虽然已经发布,但用起来明显没有macOS版顺手,组件库和抓包性能都相对弱一些。所以如果你主力机是Windows,Proxyman可能不是最优选择;如果你和我一样是Mac用户+iPhone调试,我强烈建议把这它当成Charles的替代品。
7. TraceEagle:面向取证和团队协作的新选手
7.1 它的定位和常见使用场景
TraceEagle这个名字在中文社区里还比较陌生,我最初是看一个朋友做接口安全测试时用到的,他需要把一段时间内的所有接口请求导出成完整报告,给其他同事复核。后来我试用了一下,它给我最大的感受是:这不是一个"贴身调试"的工具,而是一个"流量后处理与协查平台"。
它的工作方式跟Charles、Wireshark不一样。Charles是你本地跑一个代理,实时看流量;TraceEagle更倾向于导入已有的抓包文件(比如pcap、har格式),然后做规则分析、检索、注解和报告导出。
我举一个实际场景:线上有个环境问题,运维从服务器上抓了一个pcap包,里面混杂了好几个服务的通信。以往这种包到我手上,处理方式是扔进Wireshark,然后一个个流去找。但用TraceEagle的话,我可以直接上传pcap,它会自动把HTTP请求按域名、路径、状态码分类,还能按时间轴画出请求顺序,对着一堆乱糟糟的流量做人工审计体验好了不少。
7.2 和传统工具相比,它在流程上的变化
TraceEagle对我来说最有价值的是"团队协查"这一环。传统抓包工具的产出是一个文件,你要通过聊天工具或邮件把文件发给别人,对方还得安装同名软件才能打开,而且不相关的人看到的还是最原始的全量信息。
TraceEagle的流程是:把抓包文件上传后,可以手动过滤出关键的请求,添加注解,然后生成一条分享链接。同事在浏览器里就能查看,不需要安装任何软件,也不需要把整个pcap文件下载下来。这种模式在做安全审计、接口联调争议、客户支持排查时都很方便,省去了解释"怎么打开pcap"的过程。
当然,它也有明显的短板。作为一个年轻工具,TraceEagle的插件生态、社区教程、高级过滤语法都比Wireshark弱很多,如果你要分析的是网络层协议细节,比如TCP丢包、重传时序,它根本替代不了Wireshark。另外,它目前对本地实时抓包的体验还不够好,我用的版本仍然是"上传文件 -> 分析"的模式,做不到Charles那种"开个代理立刻看"的即时反馈。
所以我给TraceEagle的定位很明确:它适合团队协查和流量归档,不适合个人日常调试。
8. 我的选型建议和组合打法
回到最开始的问题:到底该选哪款工具?
我的个人建议是,不要陷在"哪个最好"的争论里,而是按照你的场景来匹配:
如果你的日常工作是移动App开发,电脑是Mac,手机是iPhone,那首选Proxyman,它能让你在iOS生态里少踩很多坑。
如果你的日常工作是Windows环境的接口调试、弱网测试,而且想用脚本做自动化扩展,Fiddler Classic依然能战。
如果你已经习惯Charles,并且团队里大家也都在用Charles,那没必要因为"别人说更好"就换工具,Charles的稳定性和资料数量仍然是它最值钱的资产。
如果你遇到的问题是代理层工具完全看不懂的,比如连接被重置、TCP握手超时、TLS证书校验失败、DNS解析异常,请打开Wireshark,盯着网卡看。
如果你需要给客户或者同事输出一份结构化的抓包报告,导入TraceEagle做二次整理是效率最高的路径。
组合打法是我自己在实际项目中经常用的:Charles/Proxyman负责日常接口调试和Mock,Wireshark在遇到"请求到服务端之间到底发生了什么"时介入,TraceEagle在需要归档、分享、复盘时使用。三者的关系就像手术刀、显微镜和病历本,各有各的用途,谁也替代不了谁。
抓包工具的选择不需要追求"最全面",只要能让你在最短时间内定位到问题,它就是好工具。