Dart/Flutter iOS端KeepAlive Socket连接断连无法检测问题咨询
问题核心原因
- 你的代码中定义了
RawSocketOption但没有传入Socket.connect方法,配置完全未生效 - iOS系统默认TCP KeepAlive探测策略的时间阈值极高(默认2小时才启动探测),仅开启
SO_KEEPALIVE开关无法及时触发断连回调 - 静默断网场景下(如直接关闭WiFi),TCP连接没有双向数据交互,系统无法及时感知连接失效
修复方案
1. 修正KeepAlive配置传入逻辑,补全全平台探测参数
不仅要开启SO_KEEPALIVE,还要显式配置探测间隔、重试次数、重试间隔三个核心参数,确保系统能在秒级感知断连:
Future<bool> tryConnectSocket() async { String ip = "192.168.9.101"; int port = 35000; // 统一配置KeepAlive参数:首次探测空闲等待10s,每次探测间隔2s,重试3次失败即判定断连 const keepAliveIdle = 10; const keepAliveInterval = 2; const keepAliveCount = 3; try { List<RawSocketOption> socketOptions = []; if (Platform.isAndroid) { socketOptions.add(RawSocketOption.fromBool(0x1, 0x0009, true)); // 安卓补全TCP KeepAlive参数 socketOptions.add(RawSocketOption.fromInt(6 /* IPPROTO_TCP */, 0x4 /* TCP_KEEPIDLE */, keepAliveIdle)); socketOptions.add(RawSocketOption.fromInt(6, 0x5 /* TCP_KEEPINTVL */, keepAliveInterval)); socketOptions.add(RawSocketOption.fromInt(6, 0x6 /* TCP_KEEPCNT */, keepAliveCount)); } else if (Platform.isIOS) { socketOptions.add(RawSocketOption.fromBool(0xffff /* SOL_SOCKET */, 0x0008 /* SO_KEEPALIVE */, true)); // iOS补全TCP KeepAlive参数 socketOptions.add(RawSocketOption.fromInt(6 /* IPPROTO_TCP */, 0x10 /* TCP_KEEPALIVE */, keepAliveIdle)); socketOptions.add(RawSocketOption.fromInt(6, 0x102 /* TCP_KEEPCNT */, keepAliveCount)); socketOptions.add(RawSocketOption.fromInt(6, 0x101 /* TCP_KEEPINTVL */, keepAliveInterval)); } Socket s = await Socket.connect( ip, port, timeout: const Duration(seconds: 10), // 传入配置的Socket参数 socketOptions: socketOptions ).timeout(const Duration(seconds: 10), onTimeout: () { log("ERROR ON SOCKET TIMEOUT"); return Socket.connect(ip, port, socketOptions: socketOptions); }).catchError((e) { log("ERROR ON SOCKET $e"); return Socket.connect(ip, port, socketOptions: socketOptions); }).onError((error, stackTrace) { log("ERROR ON SOCKET $error"); return Socket.connect(ip, port, socketOptions: socketOptions); }); s.listen((msg) {}, cancelOnError: false, onError: (e) { log("ERROR ON SOCKET $e"); }, onDone: () { log("Socket DONE"); }); log("DONE"); return true; } catch (e) { log("ERROR ON LISTENING TO SOCKET $e"); return false; } }
2. 新增应用层心跳机制(兼容性最佳)
系统层KeepAlive受不同厂商、系统版本的策略限制,最稳妥的方案是在应用层实现心跳逻辑:
- 每隔固定时间(如5s)向服务端发送一个极小的心跳数据包
- 若连续3次未收到服务端的心跳响应,主动关闭当前Socket,触发
onDone回调 - 该方案在iOS、Android端表现完全一致,不受系统策略影响
3. 配合网络状态监听辅助判断
接入网络状态监听工具,当系统检测到网络断开、切换时,主动校验当前Socket的可用性,若失效则主动销毁重建。
内容的提问来源于stack exchange,提问作者Mahmood Bkh
相关产品推荐
相关产品推荐

