USB vs TCP/IP Connection Modes in scrcpy: Implementation and Usage Guide
USB mode provides direct cable connectivity for minimal latency, while TCP/IP mode enables wireless debugging over Wi-Fi by routing adb commands through network sockets.
scrcpy, the popular screen mirroring tool from Genymobile, supports two distinct transport mechanisms for communicating with Android devices. Understanding the differences between USB and TCP/IP connection modes in scrcpy is essential for optimizing performance and flexibility in your development workflow.
How scrcpy Establishes Device Connections
All scrcpy communication flows through the Android Debug Bridge (adb). The tool creates a local socket forward that tunnels the scrcpy server binary and control streams between the host and device. The fundamental difference lies in whether this tunnel traverses a physical USB cable or a network socket.
USB Connection Mode
Transport Mechanism
In USB mode, scrcpy communicates over a direct USB cable connection. The adb daemon forwards a local TCP port (default 27183) to the device's abstract Unix socket scrcpy. This transport offers the highest bandwidth and lowest latency because it bypasses network stack overhead and Wi-Fi congestion.
Device Selection
When you run scrcpy without explicit network flags, the client uses the SC_ADB_DEVICE_SELECT_USB selector type defined in app/src/adb/adb.c. The sc_adb_select_device() function queries adb for USB-attached devices and selects the sole available device or the one matching a specific --serial identifier.
Configuration Steps
USB mode requires no additional configuration beyond enabling USB debugging on the device. scrcpy automatically handles the server push and port forwarding via standard adb commands.
TCP/IP Connection Mode
Transport Mechanism
TCP/IP mode routes scrcpy traffic through your Wi-Fi network. Instead of forwarding over USB, adb opens a network socket to the device's IP address on port 5555 (or a custom port). This enables wireless debugging when physical tethering is impractical.
Automatic Device Discovery
The --tcpip flag without arguments triggers sc_server_configure_tcpip_unknown_address() in app/src/server.c. This function first connects via USB to determine the device's IP address, executes adb tcpip <port> to switch the device to network mode, then reconnects over Wi-Fi. This seamless transition requires the device to be initially accessible via USB.
Manual Connection
For devices already in TCP/IP mode, specify the address directly:
scrcpy --tcpip=192.168.1.10
The sc_server_configure_tcpip_known_address() function handles this path, constructing the address string (defaulting to port 5555 when omitted) and executing adb connect. The + prefix (e.g., +192.168.1.10) forces a disconnect/reconnect cycle.
Device Selection
TCP/IP mode uses the SC_ADB_DEVICE_SELECT_TCPIP selector. When using --select-tcpip (or -e), scrcpy filters for devices connected via network transport rather than USB.
Implementation Details in the Source Code
The connection mode logic resides primarily in app/src/server.c and app/src/adb/adb.c.
In app/src/options.h, the CLI flags are defined in struct scrcpy_options:
tcpip(bool) andtcpip_dst(string) control TCP/IP behaviorselect_usbandselect_tcpipbooleans map to selector types
The run_server() function in app/src/server.c constructs the sc_adb_device_selector based on these flags. If select_usb is true, it sets type = SC_ADB_DEVICE_SELECT_USB; if select_tcpip, it uses SC_ADB_DEVICE_SELECT_TCPIP.
For TCP/IP configuration:
sc_server_configure_tcpip_unknown_address()handles the automatic USB-to-WiFi transitionsc_server_configure_tcpip_known_address()manages direct IP connections
Once the device serial (USB or IP:port) is stored in server->serial, the push_server() function uploads the scrcpy server binary. All subsequent video encoding, audio capture, and input injection operate identically regardless of transport.
Practical CLI Examples
# USB mode - simplest case (single device attached)
scrcpy
# or force USB selection when several devices are present
scrcpy --select-usb # same as `scrcpy -d`
# Automatic wireless mode (device currently connected via USB)
scrcpy --tcpip # scrcpy finds the device IP, runs `adb tcpip`,
# then reconnects over Wi-Fi and starts streaming.
# Connect to a known device already listening on TCP/IP
scrcpy --tcpip=192.168.1.10 # default port 5555 is assumed
scrcpy --tcpip=192.168.1.10:5555 # explicit port
scrcpy --tcpip=+192.168.1.10 # force reconnection (disconnect first)
# Select the only TCP/IP device (when a wireless device is already
# connected and there is no USB device)
scrcpy --select-tcpip # same as `scrcpy -e`
Summary
- USB mode leverages direct cable connections via
SC_ADB_DEVICE_SELECT_USBfor minimal latency and maximum bandwidth, requiring no additional configuration. - TCP/IP mode enables wireless debugging over Wi-Fi using
SC_ADB_DEVICE_SELECT_TCPIP, supporting both automatic discovery (viasc_server_configure_tcpip_unknown_address) and manual IP specification (viasc_server_configure_tcpip_known_address). - Both modes utilize identical server binaries and streaming protocols; only the device selection and initial handshake differ in
app/src/server.candapp/src/adb/adb.c.
Frequently Asked Questions
Does TCP/IP mode affect video quality or latency?
Yes. TCP/IP mode introduces additional network stack overhead and is susceptible to Wi-Fi congestion, which can increase latency and cause frame drops compared to direct USB transport. For high-bandwidth scenarios like 4K mirroring, USB mode is recommended according to the Genymobile/scrcpy source code.
Can I switch from USB to wireless without unplugging the cable?
Yes. Running scrcpy --tcpip without arguments automatically performs the transition. As implemented in sc_server_configure_tcpip_unknown_address() within app/src/server.c, scrcpy first connects via USB to query the device IP, executes adb tcpip to enable network debugging, then reconnects over Wi-Fi before starting the video stream.
What port does scrcpy use for TCP/IP connections?
By default, scrcpy uses port 5555 for TCP/IP connections, which is the standard adb wireless debugging port. You can specify a custom port using the syntax scrcpy --tcpip=192.168.1.10:9000. The sc_server_configure_tcpip_known_address() function in app/src/server.c handles the address parsing and defaults to port 5555 when omitted.
Is the scrcpy server binary different for USB and TCP/IP modes?
No. The server binary pushed to the Android device is identical regardless of connection mode. As implemented in push_server() within app/src/server.c, the server upload and all subsequent video encoding, audio capture, and input injection operate identically once the device serial—whether USB identifier or IP:port—is established.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →