如何在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
相关产品推荐
相关产品推荐

