adb server
运行在 PC 端,监听 localhost:5037
端口的实现原理涉及 Socket 编程、进程管理、消息处理机制 以及 客户端-服务器架构(Client-Server Architecture)。其核心机制如下:
1. ADB 的三大核心组件
adb
采用 C/S 架构(Client-Server Architecture),主要包含三部分:
adb client(客户端)
- 运行在 PC 端,用户执行
adb
命令(如adb devices
,adb forward
)。 - 负责与
adb server
通信,发送命令并处理返回的结果。
- 运行在 PC 端,用户执行
adb server(服务器)
- 运行在 PC 端,监听
localhost:5037
端口,管理多个adb
连接。 - 负责与多个
adb client
交互,并管理adbd
进程(运行在 Android 设备上)。
- 运行在 PC 端,监听
adbd daemon(守护进程)
- 运行在 Android 设备端,负责处理
adb server
发送的命令,并执行设备操作(如端口转发、文件传输、shell 命令)。 - 通过 USB 或 TCP/IP 与
adb server
进行通信。
- 运行在 Android 设备端,负责处理
2. adb server
监听 localhost:5037
的实现原理
2.1 adb server
进程启动
当执行 adb
命令(如 adb devices
)时:
adb client
首先检查adb server
是否已运行:LocalSocket socket; socket.connect("localhost", 5037);
- 尝试连接
localhost:5037
端口,判断adb server
是否在运行。
- 尝试连接
如果
adb server
未运行adb client
启动adb server
进程:adb_forkserver();
adb server
在后台运行,监听localhost:5037
端口。
2.2 adb server
监听 localhost:5037
adb server
采用 TCP Server 模型:- 使用
socket(AF_INET, SOCK_STREAM, 0)
创建监听 socket。 - 绑定
localhost:5037
,监听新的adb
连接:int server_fd = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(5037); addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // 监听 127.0.0.1 bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)); listen(server_fd, 5);
INADDR_LOOPBACK
限制了adb server
只能在本机访问,确保安全性。
- 使用
等待
adb client
连接adb server
通过accept()
等待adb client
连接:int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
adb client
连接后,adb server
解析客户端发送的命令(如adb devices
、adb forward
)。
2.3 adb server
与 adbd
进程通信
建立 USB 连接
adb server
通过 USB 端口(usb_device_open()
)连接 Android 设备:usb_handle* usb = usb_device_open();
adb server
发送host:transport-usb
命令,绑定到 Android 设备。
建立 TCP 连接
- 如果
adb
采用 Wi-Fi 连接(adb connect <device_ip>:5555
),则:int device_socket = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(5555); addr.sin_addr.s_addr = inet_addr(device_ip); connect(device_socket, (struct sockaddr*)&addr, sizeof(addr));
adb server
连接adbd
,数据流通过 TCP 传输。
- 如果
数据交互
adb server
解析adb client
的请求,如adb shell
、adb push
、adb forward
,并通过 USB/TCP 发送给adbd
。adbd
执行命令后返回结果,adb server
再返回给adb client
。
3. adb server
监听 5037 的意义
管理多个设备
adb server
统一管理所有连接的 Android 设备,包括 USB 和 TCP/IP 设备。
提高效率
- 避免每次
adb
命令都重新建立与adbd
的连接,减少资源消耗。
- 避免每次
允许并发命令
- 多个
adb client
可以同时向adb server
发送命令,例如:adb shell adb push file.txt /sdcard/
adb server
处理多个请求,提高并发能力。
- 多个
4 在中转机上运行 ADB
###############
# 在中转机上跑
###############
sudo killall adb
sudo nohup adb -a nodaemon server &
sudo adb devices
ADB_ID=ABCD1234 # adb devices 显示的设备ID
sudo adb -s ${ADB_ID} tcpip 5555
sleep 3
sudo adb -s ${ADB_ID} forward tcp:5555 tcp:5555
sudo adb -s ${ADB_ID} forward tcp:8000 tcp:8000
###############
# 在测评机上跑
###############
adb connect 100.10.20.3:5555
这段脚本的作用是 在一台“中转机”上运行 ADB 代理,然后 在另一台“测评机”上通过 ADB 远程连接 Android 设备。整个流程可以分为 “中转机设置” 和 “测评机连接” 两个部分。
4.1 在中转机上运行 ADB 代理
sudo killall adb
- 终止所有正在运行的
adb
进程,确保 ADB 重新启动时不会有冲突。
sudo nohup adb -a nodaemon server &
- 启动
adb server
,并使其在后台运行:-a
:监听所有网络接口(默认adb server
只监听localhost
)。nodaemon
:不以守护进程方式运行,适用于nohup
后台执行。nohup
:防止进程因 SSH 断开而退出。
4.2 确保设备连接
sudo adb devices
- 列出所有已连接的设备,格式:
List of devices attached ABCD1234 device
- 这里的
ABCD1234
是 Android 设备的唯一标识符(serial number
)。
ADB_ID=ABCD1234 # adb devices 显示的设备ID
- 将设备 ID 存入变量,方便后续使用。
4.3 切换 ADB 到 TCP/IP 模式
sudo adb -s ${ADB_ID} tcpip 5555
- 让 Android 设备开启 TCP/IP ADB 监听:
- 设备上的
adbd
进程会开始监听 TCP 端口 5555,允许远程 ADB 连接。 - 设备必须已启用
adb
调试模式,并连接到 USB,否则命令会失败。
- 设备上的
sleep 3
- 等待 3 秒,确保
adbd
进程成功切换到tcpip
模式。
4.4 在中转机上做端口转发
sudo adb -s ${ADB_ID} forward tcp:5555 tcp:5555
- 端口转发(Forwarding):
- 让 中转机的
localhost:5555
代理 Android 设备的localhost:5555
。 - 这样,外部设备可以通过
中转机:5555
访问 Android 设备的adb
端口。
- 让 中转机的
sudo adb -s ${ADB_ID} forward tcp:8000 tcp:8000
- 额外转发 端口 8000,可能用于 Android 设备上运行的某个 Web 服务或调试工具(如
WebSocket
或gRPC
)。
adb connect 10.1.2.3:5555
- 让测评机 通过网络连接到中转机(10.1.2.3)的
5555
端口:10.1.2.3
是中转机的 IP 地址。- 因为中转机 已将
5555
端口转发到 Android 设备,所以测评机的adb connect
最终连接的是 Android 设备。
步骤 | 命令 | 作用 |
---|---|---|
1. 杀死旧的 ADB 进程 | sudo killall adb |
避免冲突 |
2. 启动 ADB 服务器 | sudo nohup adb -a nodaemon server & |
监听 ADB 连接 |
3. 获取设备 ID | adb devices |
识别 Android 设备 |
4. 启用 TCP/IP ADB | adb -s ${ADB_ID} tcpip 5555 |
让 Android 设备监听 5555 端口 |
5. 端口转发(ADB 代理) | adb -s ${ADB_ID} forward tcp:5555 tcp:5555 |
让中转机监听 5555 端口 |
6. 测评机连接 | adb connect 10.1.2.3:5555 |
远程访问 Android 设备 |
4.7 防止 ADB 断连
如果 Android 设备 adbd
进程自动关闭,导致 adb connect
失效,可以:
while true; do adb connect 10.1.2.3:5555; sleep 5; done
- 每 5 秒尝试重新连接。
4.8 让 ADB 连接更稳定
在 Android 设备上执行:
setprop service.adb.tcp.port 5555
stop adbd
start adbd
- 使 ADB 端口持久化,避免设备重启后
adb tcpip 5555
失效。
5 adb tcpip 5555 adb forward
都是 ADB (Android Debug Bridge) 中用于网络通信的命令,但它们的功能和应用场景是不同的。下面详细说明这两者的区别:
1. adb tcpip 5555
命令:
adb tcpip 5555
功能:
adb tcpip
命令将 ADB 服务器设置为通过 TCP/IP 协议 来与设备通信,而不是通过 USB 连接。- 通过这个命令,你可以让设备监听 TCP 端口
5555
(或指定的端口)来接受 ADB 请求。这意味着你可以通过网络(如 Wi-Fi)连接到 Android 设备,而不需要使用 USB 连接。
应用场景:
- 该命令通常用于启用 Wi-Fi ADB 功能,这样你就可以通过局域网连接设备,而无需直接使用 USB 数据线。
- 使用此命令时,设备和计算机必须处于同一局域网中。
工作原理:
- 设备通过 USB 连接后,执行
adb tcpip 5555
,这会使设备开启 TCP/IP 监听端口5555
。 - 然后,你可以使用以下命令通过网络连接设备:
adb connect <device_ip>:5555
- 连接成功后,你就可以通过 Wi-Fi 与设备进行交互,例如执行 ADB 命令、文件传输等。
注意事项:
- 启用
adb tcpip
后,设备依旧通过 USB 连接到电脑,直到你执行了adb connect
连接设备。 - 一旦切换为 TCP/IP 模式,你就可以断开 USB 连接,设备仍然保持通过 Wi-Fi 进行调试。
2. adb forward
命令:
adb forward <local> <remote>
功能:
adb forward
命令用于将本地端口 (local
) 转发到设备上的远程端口 (remote
)。这允许你通过本地计算机访问设备上的某个端口。- 它通常用于将某些服务或端口从 Android 设备转发到计算机,以便在本地机器上访问该服务。
应用场景:
- 用于 端口转发,例如,将 Android 设备上的一个端口转发到计算机本地的某个端口。
- 常用于调试网络应用或进行端口映射,例如,开发者通过 ADB 调试 Android 应用时将应用的网络服务端口转发到本地计算机。
工作原理:
- 使用
adb forward
命令来创建端口转发。- 比如,
adb forward tcp:6100 tcp:7100
将设备的 7100 端口映射到计算机的 6100 端口。
- 比如,
- 在此后,你可以通过本地计算机的端口 6100 来访问设备上的服务,或者进行调试等操作。
示例:
adb forward tcp:8080 tcp:8080
这个命令会将设备上的端口 8080
映射到计算机本地的端口 8080
,允许你从计算机访问设备上运行的网络服务。
注意事项:
adb forward
只适用于当前设备和 ADB 会话。它没有像adb tcpip
那样通过网络进行连接,而是保持设备通过 USB 或 TCP/IP 与主机的连接。
区别总结
特性 | adb tcpip |
adb forward |
---|---|---|
功能 | 使设备在 TCP/IP 网络上接受 ADB 连接 | 将本地端口转发到设备上的远程端口 |
应用场景 | 启用 Wi-Fi 调试(ADB over TCP/IP) | 将设备上的服务端口转发到本地机器上 |
连接方式 | 通过网络连接(如 Wi-Fi) | 通过 USB 或 TCP/IP 与设备建立连接后进行端口转发 |
命令格式 | adb tcpip <port> |
adb forward <local> <remote> |
工作原理 | 开启设备的 TCP/IP 模式,使其监听指定端口 | 映射设备的某个端口到本地端口 |
是否需要 USB 连接 | 需要(至少在初始时通过 USB 启动) | 需要(只要设备连接通过 USB 或 Wi-Fi) |