Flutter安卓模拟器间TCP Socket连接被拒绝问题求助
解决Flutter模拟器间TCP Socket连接拒绝问题
核心问题分析
你遇到的Connection Refused错误和端口号不匹配,主要源于三个关键点:模拟器网络特性、端口绑定的实际值、连接目标IP的错误使用。
1. 端口号不匹配的原因
你手动设置了myPort = 43761,但错误信息里的端口是36802,这说明ServerSocket.bind并未成功绑定你指定的端口(大概率是端口被系统占用),自动分配了一个随机端口。但你传给客户端的还是预设的43761,导致客户端连接了错误的端口,触发连接拒绝。
解决方法:
绑定成功后获取实际监听的端口,而非依赖手动设置的值:
mySocket.then((ServerSocket listenSocket) { // 打印实际绑定的端口,传给客户端时必须用这个值 print("实际监听端口: ${listenSocket.port}"); listenSocket.listen((Socket mysocket) { mysocket.listen((Uint8List data) async { String strData = utf8.decode(data); print(strData); if(strData == "///initiate"){ mysocket.add(utf8.encode("Got your message")); } }); }); });
2. 模拟器间的网络连接问题
Android模拟器默认采用NAT网络模式,每个模拟器都是独立的虚拟环境,直接用0.0.0.0或127.0.0.1无法跨模拟器连接:
0.0.0.0是监听所有网卡的绑定地址,不是连接用的目标地址,客户端不能用它发起连接。10.0.2.2是模拟器指向宿主机的回环地址,仅适用于连接宿主机上的服务,跨模拟器不能直接使用。
两种可行的连接方案:
方案一:端口转发(推荐)
在Android Studio终端给服务端模拟器设置端口转发,把模拟器内部的监听端口映射到宿主机端口:
# 替换emulator-5554为你的服务端模拟器设备号(用adb devices查看) # 替换43761为服务端实际监听的端口,8888为宿主机的端口 adb -s emulator-5554 forward tcp:8888 tcp:43761
客户端模拟器使用10.0.2.2(宿主机地址)加宿主机端口8888连接:
p2pSocket = await Socket.connect("10.0.2.2", 8888);
方案二:使用模拟器的局域网IP
找到服务端模拟器的实际局域网IP:
- 在Android Studio终端执行
adb shell ip addr show - 找到
wlan0下的inet地址(通常是10.0.2.15或类似) - 客户端用该IP加服务端实际监听的端口发起连接。
3. 必要权限配置
确保AndroidManifest.xml中添加了网络权限,否则Socket连接会被系统拦截:
<manifest ...> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ... </manifest>
4. 代码细节修正
服务端代码中你用全局变量p2pSocket.add回复消息,这会导致空指针或发送对象错误,应该用当前新建立的连接mysocket来回复,修正后的监听代码见上文示例。
内容的提问来源于stack exchange,提问作者sfrhata
相关产品推荐
相关产品推荐

