18、网络调试:adb shell netstat、ping、curl 与 adb forward

网络调试,说白了就是让手机和电脑之间能「好好说话」。很多同学觉得这玩意儿难,其实拆开来看,每个工具都挺朴素的。我刚开始接触 Android 调试时,也对着黑乎乎的终端发过呆——后来发现,只要搞懂这几个命令,大部分网络问题都能手到擒来。

本章核心脉络:从查看网络状态(netstat),到连通性测试(ping),再到 HTTP 请求(curl),最后是端口转发(forward)。一条线串下来,你就能在电脑上操控手机的网络行为。

adb 网络调试工具全家桶 adb shell 网络命令 netstat 查看端口 & 连接状态 ping 连通性 & 延迟测试 curl HTTP 请求 & 接口调试 adb forward 端口转发 & 代理 四个工具覆盖了「看状态 → 测连通 → 发请求 → 转端口」的完整链路

18.1 查看网络状态:adb shell netstat

netstat 这个命令,说白了就是让你看看手机当前开了哪些端口、哪些程序在监听、哪些连接还活着。我个人的习惯是,遇到「连不上服务」的问题时,第一件事就是跑一下 netstat,看看端口到底有没有在监听。

基本用法很简单:

adb shell netstat -tlnp

参数说明:

  • -t:只看 TCP 连接
  • -l:只显示正在监听的端口
  • -n:以数字形式显示地址和端口(不解析域名)
  • -p:显示对应的进程 PID 和名称

举个例子,输出大概长这样:

Proto Recv-Q Send-Q  Local Address          Foreign Address        State       PID/Program Name
tcp        0      0  0.0.0.0:5555           0.0.0.0:*              LISTEN      1234/adbd
tcp        0      0  127.0.0.1:8080         0.0.0.0:*              LISTEN      5678/com.example.app

看到 0.0.0.0:5555 了吗?这就是 adbd 在监听。如果你发现某个端口没起来,别急着怀疑代码——先看看是不是进程根本没启动。

小技巧:如果你只想看某个特定端口,可以配合 grep 过滤。比如 adb shell netstat -tlnp | grep 8080,一秒定位。

我曾经遇到过一个问题:App 里的 WebSocket 服务怎么都连不上,查了半天代码,最后用 netstat 一看——端口根本没在监听。原来是服务启动时抛了个异常,日志被淹没了。嗯,从那以后我养成了「先看端口,再查日志」的习惯。

18.2 连通性测试:adb shell ping

ping 这个命令,大家应该都不陌生。它用 ICMP 协议发个包过去,看看对方能不能回你。说白了就是「嘿,你在吗?」

在 Android 上跑 ping,和电脑上差不多:

adb shell ping -c 4 8.8.8.8

-c 4 表示发 4 个包就停。如果不加这个参数,它会一直 ping 下去,你得按 Ctrl+C 才能停。

输出示例:

PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=32.5 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=31.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=33.1 ms
64 bytes from 8.8.8.8: ttl=118 time=32.0 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 31.8/32.35/33.1/0.49 ms

重点关注两个指标:

  • 丢包率:0% 最好,有丢包说明网络不稳定
  • 平均延迟:一般 30-50ms 算正常,超过 100ms 就要留意了

注意:有些设备或网络环境会禁止 ICMP 包,这时候 ping 会显示「100% packet loss」,但不一定代表网络不通。你可以换个方式,比如用 curl 去访问一个 HTTP 服务来验证。

我个人习惯在测试 App 的网络功能前,先 ping 一下目标服务器。如果 ping 不通,那后面的事就不用折腾了——先修网络再说。

18.3 HTTP 请求:adb shell curl

curl 是个好东西。它可以在终端里直接发 HTTP 请求,看返回数据。在 Android 上调试接口时特别有用——你不用写代码,不用装 Postman,一条命令搞定。

基本用法:

adb shell curl -v http://httpbin.org/get

-v 表示 verbose,会输出请求头和响应头的详细信息。

如果你想发 POST 请求,带 JSON 数据:

adb shell curl -X POST -H "Content-Type: application/json" -d '{"key":"value"}' http://httpbin.org/post

参数拆解:

  • -X POST:指定请求方法
  • -H:添加请求头
  • -d:发送的数据体

输出示例(简化版):

> POST /post HTTP/1.1
> Host: httpbin.org
> Content-Type: application/json
> Content-Length: 16
>
< HTTP/1.1 200 OK
< Content-Type: application/json
<
{
  "json": {"key": "value"}
}

你看,请求发出去,服务器返回了 JSON。整个过程一目了然。

实用场景:我在调试某个 App 的登录接口时,发现客户端一直报 401。用 curl 模拟同样的请求,发现是签名算法写错了。如果没有 curl,我可能得在代码里加一堆日志才能定位到问题。

curl 还支持很多高级功能,比如:

  • --connect-timeout 5:设置连接超时时间
  • --max-time 10:设置整个请求超时时间
  • -o /sdcard/output.txt:把响应保存到文件

18.4 端口转发:adb forward

adb forward 是我个人觉得最实用的功能之一。它可以把电脑上的某个端口,映射到手机上的某个端口。说白了就是:你在电脑上访问 localhost:8080,实际上访问的是手机上的某个服务。

基本语法:

adb forward tcp:电脑端口 tcp:手机端口

举个例子:

adb forward tcp:8080 tcp:8080

这条命令的意思是:电脑上的 8080 端口,转发到手机上的 8080 端口。之后你在电脑浏览器里打开 http://localhost:8080,就能访问手机上的服务了。

查看当前有哪些转发规则:

adb forward --list

输出示例:

emulator-5554 tcp:8080 tcp:8080

删除转发规则:

adb forward --remove tcp:8080

或者一次性清空所有规则:

adb forward --remove-all

经典应用场景:调试 WebView 里的 H5 页面。你可以在手机上打开 App,然后在电脑上通过 localhost 访问手机上的本地服务器,直接调试页面。省去了反复上传文件的麻烦。

我曾经用 adb forward 做过一个有意思的事:手机上的 App 跑了一个 Python 的 HTTP 服务器(通过 Termux),我把电脑的 5000 端口转发到手机的 5000 端口,然后在电脑上直接调用手机上的 API。嗯,调试效率直接翻倍。

注意:adb forward 只支持 TCP 协议,不支持 UDP。如果你需要转发 UDP 流量,得用 adb reverse 或者其他工具。

18.5 综合实战:一条龙排查网络问题

假设你遇到一个问题:App 连不上服务器。你可以按这个流程来排查:

  1. 看状态adb shell netstat -tlnp,确认端口是否在监听
  2. 测连通adb shell ping 服务器IP,确认网络是否可达
  3. 发请求adb shell curl -v http://服务器IP:端口/路径,确认接口是否正常
  4. 转端口:如果需要从电脑访问手机上的服务,用 adb forward 映射端口

这一套组合拳打下来,90% 的网络问题都能定位到。剩下的 10%,嗯,那可能是玄学问题——重启一下试试?

我的经验:别小看这些基础命令。我见过不少开发者,遇到网络问题第一反应是改代码,结果改了半天发现是 WiFi 没连上。先排查,再动手,能省很多时间。


公众号:蓝海资料掘金营,微信deep3321