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

Flutter使用udp包在iOS14下本地网络广播报errno=9错误

错误产生原因
  • iOS 14及以上系统新增本地网络权限限制,应用未提前申请对应权限时,系统会主动拦截本地网络广播请求,直接关闭已绑定的UDP socket,导致后续操作引用无效的文件描述符,触发OS Error: Bad file descriptor, errno = 9报错。
  • 现有代码未显式开启UDP socket的广播标识,iOS系统默认禁止普通UDP socket发送广播数据包,会直接触发socket回收关闭。
  • 部分版本的第三方udp包iOS端实现存在时序缺陷,bind操作完成后未正确持有socket句柄,短时间内连续调用listen和send方法时可能出现句柄提前释放的问题。
解决方案

步骤1:配置iOS端权限

打开iOS项目下的ios/Runner/Info.plist文件,添加两项权限配置:

  1. 添加本地网络使用说明:key为NSLocalNetworkUsageDescription,value填写业务相关的权限提示文案,例如「需要访问本地网络以发现同网段设备」
  2. 添加广播服务声明:key为NSBonjourServices,类型为数组,添加一个值为_udp._local的item

步骤2:调整UDP逻辑代码

显式开启socket广播属性,调整调用时序避免异步问题,修改后的参考代码如下:

var endPoint = Endpoint.broadcast(port: Port(6000));
var udpFuture = UDP.bind(Endpoint.any(port: Port(6000)));
udpFuture.then((udp) async {
  // 显式开启socket广播权限,适配iOS系统限制
  udp.socket.broadcastEnabled = true;
  // 初始化监听
  udp.listen((datagram) {
    handleMessage(datagram.data);
  });
  // 增加短延时规避iOS端socket初始化时序问题
  await Future.delayed(const Duration(milliseconds: 100));
  udp.send(bytesToSend, endPoint);
});

备选方案

如果第三方udp包仍存在兼容问题,可直接使用Dart标准库dart:io中的RawDatagramSocket实现UDP广播,原生实现对iOS14+系统的适配稳定性更高。

内容的提问来源于stack exchange,提问作者Roy Solberg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:06:02