ITPub博客

首页 > 移动开发 > IOS > WebSocket 抓包怎么改帧?TraceEagle 的逐帧查看与方向改写

WebSocket 抓包怎么改帧?TraceEagle 的逐帧查看与方向改写

原创 IOS 作者:栈溢出日常 时间:2026-10-21 10:40:12 0 删除 编辑

WebSocket 抓包和抓 HTTP 接口,第一眼看过去像两种东西。调一个 REST 接口,列表里一条请求配一条响应,点开就能看到参数和返回值;换成 WebSocket,请求列表里一般只有一条连接,点进去却挂着几十上百条消息,上行下行混在一起,中间还夹着几个看不懂的二进制帧。

这就是 WebSocket 调试容易卡住的地方——别按请求-响应的思路看它,它是一条长连接上的持续对话。TraceEagle 把这条连接拆成逐帧的消息视图,也能按方向对帧做替换。它和 HTTP 抓包有四个不一样的地方:一条连接串起整段会话、每帧都带方向、帧分文本和二进制、帧发生在 HTTP 升级之后。四个点挨个展开,顺带把改帧的思路理一遍。

一、变化点一:一条连接,串起整段会话

HTTP 的查看单位是"一次请求",WebSocket 的查看单位是"一条连接"。

连接建立之后,客户端和服务端会在这条连接上不停地收发消息。你在请求列表里看到的那一条,背后可能已经跑了几百帧。所以别在列表里找"这条消息对应的响应"——没有这种东西。要看内容,得点进这条连接,进帧视图。

帧视图里一条一条列着收发记录,标了方向、类型和时间。刚连上时的握手、订阅、鉴权,中间的业务消息,断开前的 close 帧,都在里面。先别急着找规律,从头往下扫一遍吧。我第一次看的时候也愣了几秒(习惯性地去找 response,结果发现整个会话就是一条流)。

二、变化点二:每一帧都有方向

HTTP 的请求和响应天然分在两边,WebSocket 不是。同一条连接上,两个方向的消息混在一个列表里,所以方向标签不是装饰,是你判断问题的第一依据。

上行,也就是客户端发给服务器的那一侧,一般是建立连接、鉴权、订阅主题、用户操作、心跳。下行是服务器推给客户端的,一般是推送、广播、状态同步、确认回执。

消息没收到的时候,先确认它应该走哪个方向呢。如果一条"服务器推送"被写成了上行,那不管你怎么查服务端,都对不上——方向错了,后面基本白搭。其实方向本来就标在每一帧上,只是混在一起的时候容易看漏。

三、变化点三:帧不是只有文本

WebSocket 帧有几种类型,调试时最好分得清:

  • 文本帧:里面一般是 JSON 或普通字符串,直接能读。
  • 二进制帧:可能是 protobuf、MessagePack,也可能是自定义格式。帧视图里看到的是字节,得先知道协议才能解释。
  • ping / pong:心跳,很多客户端和服务端会自动回,不是业务消息。
  • close:关闭连接。

扫帧的时候,顺手把 ping / pong 跳过去,重点看文本和二进制。二进制帧别按 JSON 的思路硬套,先确认编码再说——不然很容易把正常的二进制内容当成乱码,对着它折腾半天啊。

四、变化点四:帧在 HTTP 升级之后才开始

WebSocket 的连接是"借"HTTP 建立的:客户端先发一个带 Upgrade: websocket 的 GET 请求,服务端回 101 Switching Protocols,这条连接当场切成 WebSocket 帧协议。RFC 6455 里写得很清楚。

这件事对抓包有两个影响。

一是 wss 必须先解密。如果是加密连接,证书没装好、连接没解开,你连升级请求都看不到明文,更别说后面的帧。代理会话、证书、解密范围这几步,和抓普通 HTTPS 是一样的。

二是规则要能命中这条连接。改帧的规则还是按域名、路径这类条件匹配,命中的连接才谈得上在内部改帧。连接都没进代理,规则写得再对也没用嘛。

五、按方向改帧:规则怎么写

在 TraceEagle 的规则面板里,从速查表选 WebSocket 帧改写,方向选好,再写替换关系。方向有三个选项:

方向 改哪一侧的帧 适合的场景
客户端→服务器 上行 改提交的参数、订阅的主题、上行的指令
服务器→客户端 下行 改推送内容、状态同步、错误码
双向 两边 同一个字段上行下行都会出现

替换关系写成 old=>new,也就是把帧里出现的 old 换成 new。规则保存即生效,不用重连。

举几个实际会用到的场景:聊天类应用里把指定的测试文案换掉、协作编辑里改一个占位符、推送消息里把某个状态码换成另一个值。这些都不用动客户端代码,改的是经过代理的那一份帧,改完立刻就能看到客户端怎么反应。

这里有两个细节值得提前知道。

第一,替换是按字面匹配的。大小写、空格、引号、转义都得对上。JSON 里的字段名带引号,你就把引号一起写进去;少一个字符都换不掉。

第二,动态变量支持 ${...},但命名值 {name} 在帧改写里不生效。这一点在产品文档的排查表里专门写了一句。想用时间戳、随机值,直接写 ${now}、 ${randomUUID} 这类;别把 HTTP 改写里那套命名值搬过来,搬过来只会得到原样输出。

方向选错也很常见。明明要改服务端推下来的内容,规则却挂在上行,帧一点变化都没有。改之前先想清楚这条消息是谁发给谁的,比反复改规则省事得多。

六、改完怎么验证

让客户端再发一次消息,回到帧视图看新出来的那一帧。内容变了,说明规则命中了;没变,按这个顺序查:

  1. 规则保存了没有,所在分组是不是开着。
  2. 匹配有没有命中这条连接——域名、路径对不对。
  3. 方向选得对不对——改下行却选了上行,肯定不会生效。
  4. 连接是不是已经解密——密文状态下谈不上改帧。

还有一个容易忽略的点:帧改写挂在连接上,连接重连之后,只要规则还匹配,就继续生效。不用为每次重连单独配置。

七、和别的工具比一比

WebSocket 抓包不只代理这一条路,顺手比一比。

浏览器 DevTools 的 Network 面板能看 WebSocket 帧,当前页面用起来最方便。局限也明显:只管这一个页面,原生 App、别的设备、命令行程序都够不着,批量改帧也不是它的活。

Wireshark 更偏底层,能解 WebSocket 帧,也能看到 TCP 层的重传、分片、拥塞。排查"帧为什么没到"这类网络问题时,它比应用层工具更有说服力。改流量不是它的目标。

Charles、Fiddler、Proxyman 这一路都在代理层,也能看 WebSocket。要改帧,就得看各自的规则或脚本能力,做法不太一样。

mitmproxy 用脚本处理 WebSocket 消息,灵活度最高,代价是要写代码。

TraceEagle 的定位是把"看"和"改"放在同一套规则里:HTTP 的改写、弱网、断点、WebSocket 帧改写,共用一套匹配和分组。手机上、原生 App 里的连接,也能落到同一个会话里看。它当然替代不了 Wireshark 的协议深度,两者管的是不同层的问题。

WebSocket 调试的难点不在帧本身,在习惯。把它当成一条持续对话,先看方向、再看类型,再往后才谈改不改。帧里的内容不对,先确认是哪一侧发的;要改,就把方向选对、把 old=>new 写准。

下次遇到"服务端明明推了、客户端就是没收到",别急着翻代码。先把那条连接点开,看看帧到底有没有出来吧。反正我是这么查的,十有八九能少走一段弯路。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047460/viewspace-3186245/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2025-09-06

  • 博文量
    133
  • 访问量
    135732