
scrcpy 设备连接完全指南设备选择、无线 TCP/IP 连接与源码实现剖析【免费下载链接】scrcpyDisplay and control your Android device项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy本文基于 scrcpy 官方文档 Connection 与客户端源码系统讲解多设备环境下的设备选择机制--serial/--select-usb/--select-tcpip/--tcpip、ANDROID_SERIAL环境变量、无线 TCP/IP 连接的自动与手动两种模式并结合 app/src/adb/adb.c 与 app/src/server.c 中的实际调用链剖析这些选项在底层是如何解析adb devices -l输出、判定设备类型、自动完成 USB 到 TCP/IP 切换的。读完后你可以独立完成多设备指定、免数据线投屏并能读懂 scrcpy 连接阶段的日志输出。一、设备选择Selectionscrcpy 通过adb枚举设备。当adb devices恰好只列出一台设备时scrcpy 会自动选中它无需任何参数。当连接了多台设备时必须用以下 4 种方式之一指定目标设备1. 通过序列号serial选择scrcpy --serial0123456789abcdef scrcpy -s 0123456789abcdef # 短选项 # 通过 TCP/IP 连接时serial 就是 ip:port行为与 adb 一致 scrcpy --serial192.168.1.1:55552. 指定 USB 设备要求恰好只有一台scrcpy --select-usb scrcpy -d # 短选项3. 指定 TCP/IP 设备要求恰好只有一台scrcpy --select-tcpip scrcpy -e # 短选项4. 直接连接一个已在监听 TCP/IP 的设备scrcpy --tcpip192.168.1.1:5555 scrcpy --tcpip192.168.1.1 # 默认端口为 5555此外序列号也可以通过环境变量ANDROID_SERIAL提供adb工具同样使用该变量三种常见 Shell 下的写法# in bash export ANDROID_SERIAL0123456789abcdef scrcpy:: in cmd set ANDROID_SERIAL0123456789abcdef scrcpy# in PowerShell $env:ANDROID_SERIAL 0123456789abcdef scrcpy二、源码剖析scrcpy 是如何完成设备选择的上面 4 种选择方式在源码中统一收敛为「选择器selector」机制核心实现在 sc_adb_select_device()枚举设备sc_adb_list_devices() 执行adb devices -l将输出解析为设备列表serial、state、model。解析逻辑由 app/src/adb/adb_parser.c 实现并有对应的单元测试 test_adb_parser.c 覆盖。按选择器过滤每种命令行选项对应 sc_adb_device_selector 的一个类型——SC_ADB_DEVICE_SELECT_ALL无参数、SC_ADB_DEVICE_SELECT_SERIAL-s、SC_ADB_DEVICE_SELECT_USB-d、SC_ADB_DEVICE_SELECT_TCPIP-e过滤规则见 sc_adb_accept_device()。设备类型判定sc_adb_device_get_type() 的规则非常简洁——serial 以emulator-开头判为模拟器serial 中含:判为 TCP/IP 设备因为ip:port与真实 USB serial 可以靠冒号区分其余判为 USB 设备。因此-e实际会同时选中「TCP/IP 设备和模拟器」这与 adb 的-e语义一致源码注释中亦有说明。数量校验与状态检查匹配到 0 台或多台都会报错并打印全部设备列表日志中带--标记的即候选设备匹配到 1 台后还会检查其状态sc_adb_device_check_state()adb.c#L584-L604——只有device状态可用unauthorized会提示在设备上确认授权弹窗。两个值得注意的匹配细节adb.c#L513-L534IP 前缀匹配如果设备 serial 是192.168.1.1:5555而你用--serial192.168.1.1不带端口匹配scrcpy 会截取 IP 部分做前缀比较——因此--serialIP可匹配该 IP 的任意 adb 端口这也是--tcpip192.168.1.1能自动补默认端口的基础。ANDROID_SERIAL的读取时机在 run_server() 中当未显式给出-s/-d/-e时scrcpy 会调用getenv(ANDROID_SERIAL)若设置了该变量则隐式按 serial 选择器过滤等价于scrcpy -s $ANDROID_SERIAL。命令行选项的定义见 app/src/cli.c-d/--select-usb与 app/src/cli.c-e/--select-tcpip--tcpip选项在 app/src/cli.c#L904-L906。注意三者的互斥关系在需要「先选设备」的路径上req_serial、select_usb、select_tcpip三者至多只能设置一个见 server.c#L967-L971 的断言。三、TCP/IP无线连接scrcpy 依赖adb与设备通信而adb本身支持通过 TCP/IP 连接设备。前提是设备与电脑处于同一网络。3.1 自动模式--tcpip--tcpip有两个用法用法 A不带参数设备上 adb TCP/IP 模式未开启或不知道 IP——先用 USB 连上设备然后scrcpy --tcpip # 不带参数scrcpy 会自动探测设备 IP 和 adb 端口 → 必要时开启 TCP/IP 模式 → 连接设备 → 再启动投屏。用法 B带地址设备已在监听 adb 端口通常是 5555scrcpy --tcpip192.168.1.1 # 默认端口为 5555 scrcpy --tcpip192.168.1.1:5555强制重连在地址前加前缀会先断开旧连接再连接scrcpy --tcpip192.168.1.13.2 自动模式背后的调用链整个流程集中在 app/src/server.c 的run_server()中按是否带地址分两条路径路径一--tcpip无地址→ sc_server_configure_tcpip_unknown_address()先用 USB 选出一台设备第二节的 selector 机制若该设备已经是 TCP/IP 类型则直接复用。sc_server_switch_to_tcpip() 完成「USB → TCP/IP」切换sc_adb_get_device_ip() 执行adb -s serial shell ip route并解析出设备 IPget_adb_tcp_port() 读取设备属性service.adb.tcp.port判断 TCP/IP 模式是否已开启若未开启调用 sc_adb_tcpip()即adb tcpip 55555555定义在 server.c#L23 的SC_ADB_PORT_DEFAULT然后由 wait_tcpip_mode_enabled()轮询等待每 250ms 重读一次service.adb.tcp.port最多 40 次约 10 秒直到属性值等于 5555——这一步解释了「adb tcpip执行后 adbd 需要重启、存在短暂延迟」这一现象。路径二--tcpipip[:port]已知地址→ sc_server_configure_tcpip_known_address()地址中无端口时自动补上默认端口 5555前缀会被 run_server() 检测出来先执行一次adb disconnect静默模式连接不存在时不报错再连接随后调用 sc_server_connect_to_tcpip() 执行adb connect ip:port。一个容易踩坑的底层细节adb connect无论成败退出码都是 0所以 sc_adb_connect() 不得不读取其 stdout只有输出以connected或already connected开头才判定成功否则把 adb 的报错回显到 stderr。这就是连接失败时你会在终端看到类似failed to connect to 192.168.1.1:5555输出的原因。3.3 手动模式也可以不借助--tcpip直接用adb手动完成用 USB 把设备连到电脑让设备与电脑连入同一个 Wi-Fi网络获取设备 IP在「设置 → 关于手机 → 状态信息」中查看或执行adb shell ip route | awk {print $9}在设备上启用 adb TCP/IP 模式adb tcpip 5555拔掉 USB 线连接设备adb connect DEVICE_IP:5555DEVICE_IP换成上一步查到的 IP像平常一样运行scrcpy用完后执行adb disconnect。自 Android 11 起系统还内置了「无线调试」功能可以完全跳过物理 USB 连接这一步直接通过配对码完成无线 adb 连接参见 ADB 官方文档中 wireless debugging 一节。四、自动启动Autostartscrcpy 作者维护了一个小工具AutoAdb可以在检测到新 Android 设备连接的瞬间自动执行任意命令。用它实现「设备一插上就启动 scrcpy」autoadb scrcpy -s {}其中{}是 AutoAdb 提供的占位符会被替换为新连接设备的 serial等价于scrcpy -s 新设备serial天然适配多设备环境。五、常见问题速查现象原因与处理Multiple (N) ADB devices报错多台设备时未指定选择器用-s/-d/-e指定或设置ANDROID_SERIALDevice is unauthorized设备端未确认调试授权弹窗在设备上点击允许即可报错信息会引导查看 FAQ.mdCould not find any ADB device over USB/TCP/IP-d/-e要求「恰好一台」当前一台都没有确认adb devices输出adb tcpip后一段时间才能连上adbd 重启需要时间自动模式内置了最多约 10 秒的轮询等待40 次 × 250ms手动模式建议稍等数秒再adb connect换了 Wi-Fi 后连接失败设备与电脑必须同网段重新查 IP 并adb connect适用范围说明以上行为均基于当前仓库源码验证——默认端口 5555 由 SC_ADB_PORT_DEFAULT 决定--tcpipip的强制重连、ANDROID_SERIAL兜底等细节均与文档 doc/connection.md 描述一致。若你使用 portable 版 scrcpyadb 二进制随包附带其查找逻辑见 sc_adb_init()。【免费下载链接】scrcpyDisplay and control your Android device项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考