You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android中创建监听本地端口的Socket?附相关场景需求

在Android中监听本地主机端口的Socket实现方案

嘿,我完全get你的场景——远程用户操作桌面程序触发Shell脚本发消息到本地端口,然后需要Android平板这边接住数据再处理对吧?刚好之前做过类似的USB连接下的Socket通信,下面一步步给你讲怎么实现,还会适配你的场景细节:

1. 先写Android端的Socket监听核心代码

首先,Android不能在UI线程搞网络操作,所以得用IO线程或者协程来跑监听逻辑。这里给你贴Kotlin的协程版本(现在Android开发主流用这个),Java版本的话思路是一样的,开个Thread就行:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.ServerSocket
import java.net.Socket

fun startLocalSocketListener(port: Int = 1100) {
    // 用IO线程跑监听,别卡UI
    GlobalScope.launch(Dispatchers.IO) {
        try {
            // 创建ServerSocket绑定指定端口
            val serverSocket = ServerSocket(port)
            println("[Socket] 监听已启动,端口:$port")

            // 循环等待新连接(一直监听的话就别break)
            while (true) {
                // 阻塞等待客户端连接
                val clientSocket = serverSocket.accept()
                println("[Socket] 收到新连接:${clientSocket.inetAddress}")

                // 读取发送过来的数据
                val inputStream = clientSocket.getInputStream()
                val buffer = ByteArray(1024)
                val bytesRead = inputStream.read(buffer)
                val receivedData = String(buffer, 0, bytesRead).trim()
                println("[Socket] 收到数据:$receivedData")

                // --------------------------
                // 这里写你的业务逻辑:比如把数据显示到UI,或者处理后回发
                // 示例:更新UI(必须切回主线程)
                withContext(Dispatchers.Main) {
                    // 假设你有个TextView叫tv_received_data
                    tv_received_data.text = "收到:$receivedData"
                }
                // 示例:回发确认消息给发送端
                val outputStream = clientSocket.getOutputStream()
                outputStream.write("Android已接收:$receivedData".toByteArray())
                outputStream.flush()
                // --------------------------

                // 处理完关闭当前连接
                clientSocket.close()
            }
        } catch (e: Exception) {
            e.printStackTrace()
            println("[Socket] 监听出错:${e.message}")
        }
    }
}

你可以在Activity的onCreate里调用这个方法,比如startLocalSocketListener(1100),启动监听。

2. 适配USB连接的关键:端口转发

重点来了!你的Android平板是通过USB连电脑的,默认情况下Android的localhost指的是它自己,电脑的localhost是电脑本身,两者没法直接互通。所以必须用adb命令做端口转发,分两种情况:

情况1:让Android直接接收Shell脚本发往电脑1100端口的数据

执行这条adb命令(电脑上打开终端,确保adb已经连接设备):

adb forward tcp:1100 tcp:1100

这个命令的意思是:把电脑上1100端口收到的所有数据,转发到Android设备的1100端口。这样Shell脚本往电脑的localhost:1100发数据,Android的监听代码就能直接收到。

情况2:如果是电脑端先接收数据,再转发给Android

那电脑端需要一个简单的Socket客户端,把收到的数据发送到Android的端口。这时候你需要用反向转发:

adb reverse tcp:1100 tcp:1100

这样Android里连接localhost:1100,实际会连接到电脑的1100端口,电脑端的服务端就能把数据发给Android。

3. 权限与后台运行注意事项

  • 必须加权限:在AndroidManifest.xml里加上Internet权限,不然Socket连不了:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • 后台存活问题:Android 8.0以后对后台线程限制很严,如果你的App退到后台,系统可能会杀掉监听线程。如果需要持续监听,建议把Socket逻辑放到前台服务里,给服务加个前台通知(比如显示“正在监听端口”),这样系统就不会轻易回收。

4. 小提示

  • 测试的时候,可以先用电脑上的telnet或者nc命令发数据测试,比如echo "test data" | nc localhost 1100,看看Android能不能收到。
  • 如果端口被占用了,换个端口就行,比如1101、1234这些没被系统占用的。

内容的提问来源于stack exchange,提问作者Kevin Perez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:25:30