adb端口转发

adb server 运行在 PC 端,监听 localhost:5037 端口的实现原理涉及 Socket 编程、进程管理、消息处理机制 以及 客户端-服务器架构(Client-Server Architecture)。其核心机制如下:


1. ADB 的三大核心组件

adb 采用 C/S 架构(Client-Server Architecture),主要包含三部分:

  1. adb client(客户端)

    • 运行在 PC 端,用户执行 adb 命令(如 adb devices, adb forward)。
    • 负责与 adb server 通信,发送命令并处理返回的结果。
  2. adb server(服务器)

    • 运行在 PC 端,监听 localhost:5037 端口,管理多个 adb 连接。
    • 负责与多个 adb client 交互,并管理 adbd 进程(运行在 Android 设备上)。
  3. adbd daemon(守护进程)

    • 运行在 Android 设备端,负责处理 adb server 发送的命令,并执行设备操作(如端口转发、文件传输、shell 命令)。
    • 通过 USB 或 TCP/IP 与 adb server 进行通信。

2. adb server 监听 localhost:5037 的实现原理

2.1 adb server 进程启动

当执行 adb 命令(如 adb devices)时:

  1. adb client 首先检查 adb server 是否已运行:

    cpp 复制代码
    LocalSocket socket;
    socket.connect("localhost", 5037);
    • 尝试连接 localhost:5037 端口,判断 adb server 是否在运行。
  2. 如果 adb server 未运行

    • adb client 启动 adb server 进程:

      cpp 复制代码
      adb_forkserver();
    • adb server 在后台运行,监听 localhost:5037 端口。


2.2 adb server 监听 localhost:5037

  1. adb server 采用 TCP Server 模型:

    • 使用 socket(AF_INET, SOCK_STREAM, 0) 创建监听 socket。

    • 绑定 localhost:5037,监听新的 adb 连接:

      cpp 复制代码
      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 只能在本机访问,确保安全性。

  2. 等待 adb client 连接

    • adb server 通过 accept() 等待 adb client 连接:

      cpp 复制代码
      int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &addr_len);
    • adb client 连接后,adb server 解析客户端发送的命令(如 adb devicesadb forward)。


2.3 adb serveradbd 进程通信

  1. 建立 USB 连接

    • adb server 通过 USB 端口(usb_device_open())连接 Android 设备:

      cpp 复制代码
      usb_handle* usb = usb_device_open();
    • adb server 发送 host:transport-usb 命令,绑定到 Android 设备。

  2. 建立 TCP 连接

    • 如果 adb 采用 Wi-Fi 连接(adb connect <device_ip>:5555),则:

      cpp 复制代码
      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 传输。

  3. 数据交互

    • adb server 解析 adb client 的请求,如 adb shelladb pushadb forward,并通过 USB/TCP 发送给 adbd
    • adbd 执行命令后返回结果,adb server 再返回给 adb client

3. adb server 监听 5037 的意义

  1. 管理多个设备

    • adb server 统一管理所有连接的 Android 设备,包括 USB 和 TCP/IP 设备。
  2. 提高效率

    • 避免每次 adb 命令都重新建立与 adbd 的连接,减少资源消耗。
  3. 允许并发命令

    • 多个 adb client 可以同时向 adb server 发送命令,例如:

      sh 复制代码
      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 代理

sh 复制代码
sudo killall adb
  • 终止所有正在运行的 adb 进程,确保 ADB 重新启动时不会有冲突。
sh 复制代码
sudo nohup adb -a nodaemon server &
  • 启动 adb server,并使其在后台运行:
    • -a:监听所有网络接口(默认 adb server 只监听 localhost)。
    • nodaemon:不以守护进程方式运行,适用于 nohup 后台执行。
    • nohup:防止进程因 SSH 断开而退出。

4.2 确保设备连接

sh 复制代码
sudo adb devices
  • 列出所有已连接的设备,格式:

    复制代码
    List of devices attached
    ABCD1234    device
  • 这里的 ABCD1234 是 Android 设备的唯一标识符(serial number)。

sh 复制代码
ADB_ID=ABCD1234  # adb devices 显示的设备ID
  • 将设备 ID 存入变量,方便后续使用。

4.3 切换 ADB 到 TCP/IP 模式

sh 复制代码
sudo adb -s ${ADB_ID} tcpip 5555
  • 让 Android 设备开启 TCP/IP ADB 监听
    • 设备上的 adbd 进程会开始监听 TCP 端口 5555,允许远程 ADB 连接。
    • 设备必须已启用 adb 调试模式,并连接到 USB,否则命令会失败。
sh 复制代码
sleep 3
  • 等待 3 秒,确保 adbd 进程成功切换到 tcpip 模式。

4.4 在中转机上做端口转发

sh 复制代码
sudo adb -s ${ADB_ID} forward tcp:5555 tcp:5555
  • 端口转发(Forwarding)
    • 中转机的 localhost:5555 代理 Android 设备的 localhost:5555
    • 这样,外部设备可以通过 中转机:5555 访问 Android 设备的 adb 端口。
sh 复制代码
sudo adb -s ${ADB_ID} forward tcp:8000 tcp:8000
  • 额外转发 端口 8000 ,可能用于 Android 设备上运行的某个 Web 服务或调试工具(如 WebSocketgRPC)。

sh 复制代码
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 失效,可以:

sh 复制代码
while true; do adb connect 10.1.2.3:5555; sleep 5; done
  • 每 5 秒尝试重新连接

4.8 让 ADB 连接更稳定

在 Android 设备上执行:

sh 复制代码
setprop service.adb.tcp.port 5555
stop adbd
start adbd
  • 使 ADB 端口持久化 ,避免设备重启后 adb tcpip 5555 失效。

相关推荐
北冥有鱼被烹9 小时前
【微知】rokid glass如何开启无线adb进行APP安装
adb
STER labo1 天前
mysql配置环境变量——(‘mysql‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件解决办法)
数据库·mysql·adb
sjmaysee2 天前
CentOS7安装Mysql5.7(ARM64架构)
adb·架构
AtOR CUES2 天前
MySQL——表操作及查询
android·mysql·adb
mOok ONSC2 天前
mysql9.0windows安装
windows·adb
xxjj998a2 天前
Laravel8.x核心特性详解
数据库·mysql·adb
TeDi TIVE2 天前
Linux下MySQL的简单使用
linux·mysql·adb
TeDi TIVE2 天前
MySQL四种备份表的方式
mysql·adb·oracle
rleS IONS2 天前
Linux系统离线部署MySQL详细教程(带每步骤图文教程)
linux·mysql·adb
计算机安禾3 天前
【Linux从入门到精通】第40篇:LAMP/LNMP环境一键部署脚本实战
android·linux·adb