adb端口转发

发布于:2025-02-10 ⋅ 阅读:(158) ⋅ 点赞:(0)

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 是否已运行:

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

    • adb client 启动 adb server 进程:
      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 连接:
      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 连接:
      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 设备:
      usb_handle* usb = usb_device_open();
      
    • adb server 发送 host:transport-usb 命令,绑定到 Android 设备。
  2. 建立 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 传输。
  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 发送命令,例如:
      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 服务或调试工具(如 WebSocketgRPC)。

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 数据线。
  • 使用此命令时,设备和计算机必须处于同一局域网中。
工作原理
  1. 设备通过 USB 连接后,执行 adb tcpip 5555,这会使设备开启 TCP/IP 监听端口 5555
  2. 然后,你可以使用以下命令通过网络连接设备:
    adb connect <device_ip>:5555
    
  3. 连接成功后,你就可以通过 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 应用时将应用的网络服务端口转发到本地计算机。
工作原理
  1. 使用 adb forward 命令来创建端口转发。
    • 比如,adb forward tcp:6100 tcp:7100 将设备的 7100 端口映射到计算机的 6100 端口。
  2. 在此后,你可以通过本地计算机的端口 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)

网站公告

今日签到

点亮在社区的每一天
去签到