部分Android 13设备Socket连接出现ECONNREFUSED问题求助
解决部分Android 13设备Socket连接ECONNREFUSED问题
问题概述
Socket连接到192.171.1.1:1234时,仅在三星Galaxy M32、F23(Android 13)设备上抛出ECONNREFUSED异常,其他Android版本及部分Android 13设备(一加OxygenOS 13.1、红米Android 13)可正常连接,且服务器已通过TCP/UDP工具验证运行正常。
解决方案
1. 确认网络权限配置
Android 13针对局域网连接新增权限要求,需在AndroidManifest.xml中声明必要权限,并动态申请(若targetSdkVersion ≥33):
<!-- 基础网络权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Android 13+ 局域网Wi-Fi设备访问权限 --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" android:usesPermissionFlags="neverForLocation" />
动态申请代码示例:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) { ActivityResultContracts.RequestPermission requestPermission = new ActivityResultContracts.RequestPermission(); registerForActivityResult(requestPermission, isGranted -> { // 处理权限申请结果 }).launch(Manifest.permission.NEARBY_WIFI_DEVICES); } }
2. 强制使用IPv4连接
异常日志显示连接从IPv6地址/::发起,部分三星设备默认优先IPv6,但服务器可能仅监听IPv4,导致连接失败。修改Socket创建逻辑,强制绑定IPv4:
try { InetAddress targetIp = InetAddress.getByName("192.171.1.1"); hoistronSocket = new Socket(); // 绑定到IPv4本地地址 hoistronSocket.bind(new InetSocketAddress(InetAddress.getByName("0.0.0.0"), 0)); // 设置10秒连接超时 hoistronSocket.connect(new InetSocketAddress(targetIp, 1234), 10000); } catch (Exception e) { Log.d("Hoistron:Except", "连接失败", e); if (e.getMessage() != null && e.getMessage().contains("ECONNREFUSED")) { showFailedDialogBox(); } }
也可在Manifest中全局禁用IPv6:
<application ... android:usesCleartextTraffic="true"> <meta-data android:name="android.net.ipv6" android:value="false" /> </application>
3. 检查三星设备专属网络限制
三星One UI可能存在额外网络管控,需引导用户检查:
- 进入设置 > 应用 > 你的应用 > 权限,确保已授予网络权限
- 关闭Wi-Fi优化:设置 > 连接 > Wi-Fi > 高级 > Wi-Fi优化,禁用该功能
- 检查智能管理器中的应用网络访问限制,确保未阻止应用连接局域网
4. 添加连接超时与重试机制
当前代码未设置连接超时,且无重试逻辑,易受网络波动影响。优化代码如下:
int maxRetries = 3; boolean isConnected = false; Socket socket = null; while (maxRetries > 0 && !isConnected) { try { InetAddress targetIp = InetAddress.getByName("192.171.1.1"); socket = new Socket(); socket.connect(new InetSocketAddress(targetIp, 1234), 10000); isConnected = true; hoistronSocket = socket; } catch (Exception e) { Log.d("Hoistron:Except", "重试连接,剩余次数:" + maxRetries, e); maxRetries--; // 关闭失败的Socket if (socket != null) { try { socket.close(); } catch (IOException ignored) {} } // 间隔1秒重试 try { Thread.sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } if (!isConnected) { showFailedDialogBox(); }
5. 再次验证服务器配置
确认服务器监听地址为0.0.0.0(允许所有IP访问),而非127.0.0.1(仅本地访问);同时检查服务器防火墙是否允许1234端口的TCP入站连接。
内容的提问来源于stack exchange,提问作者Nandu
相关产品推荐
相关产品推荐

