18、网络调试:adb shell netstat、ping、curl 与 adb forward
网络调试,说白了就是让手机和电脑之间能「好好说话」。很多同学觉得这玩意儿难,其实拆开来看,每个工具都挺朴素的。我刚开始接触 Android 调试时,也对着黑乎乎的终端发过呆——后来发现,只要搞懂这几个命令,大部分网络问题都能手到擒来。
本章核心脉络:从查看网络状态(netstat),到连通性测试(ping),再到 HTTP 请求(curl),最后是端口转发(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 连不上服务器。你可以按这个流程来排查:
- 看状态:
adb shell netstat -tlnp,确认端口是否在监听 - 测连通:
adb shell ping 服务器IP,确认网络是否可达 - 发请求:
adb shell curl -v http://服务器IP:端口/路径,确认接口是否正常 - 转端口:如果需要从电脑访问手机上的服务,用
adb forward映射端口
这一套组合拳打下来,90% 的网络问题都能定位到。剩下的 10%,嗯,那可能是玄学问题——重启一下试试?
我的经验:别小看这些基础命令。我见过不少开发者,遇到网络问题第一反应是改代码,结果改了半天发现是 WiFi 没连上。先排查,再动手,能省很多时间。
公众号:蓝海资料掘金营,微信deep3321