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

Flutter网络检测状态异常导致sendEmail触发SocketException

问题根因
  • 异步调用未等待结果:checkUserConnection()是返回Future的异步方法,你在onTap回调中直接调用时没有加await等待执行完成,调用后会立刻往下执行activeConnection的判断逻辑。此时DNS域名检测的逻辑还在后台运行,activeConnection还是上一次检测留存的true值,根本没拿到最新的断网状态,就直接触发了sendEmail(),自然会报主机查找失败的异常。
  • 同步sleep完全无效:你之前加的sleep(const Duration(seconds: 10))是同步阻塞方法,会卡住当前主Isolate的所有事件循环(包括网络IO、UI更新、DNS查询),不仅不会给网络状态切换留缓冲时间,反而会让检测逻辑卡到sleep结束后才执行,而外层的判断逻辑根本不会等sleep跑完,完全起不到等待作用。
  • 缺乏异常兜底:你把前置网络检测作为判断能否发邮件的唯一依据,但网络状态本身是随时可变的——就算检测时网络正常,发送邮件的过程中也可能出现断网、DNS解析失败的问题,没有给sendEmail()加异常捕获的话,任何网络波动都会直接抛出未捕获异常。
修复方案
  • 调整异步调用逻辑,必须等待检测完成再执行后续判断:把onTap回调改成async函数,调用checkUserConnection()时加await,等检测完全结束拿到结果后再判断是否发邮件。同时优化checkUserConnection的返回值,直接返回布尔类型的网络状态结果,不要依赖类成员变量传值,从根源上避免时序导致的状态不一致问题。
  • 替换无效的同步sleep:如果需要给网络状态切换留几百毫秒的系统同步缓冲时间,用非阻塞的await Future.delayed(),不会卡住事件循环。
  • 给邮件发送逻辑加异常兜底:sendEmail()执行时必须捕获SocketException等网络相关异常,就算前置检测通过,发送过程中出现网络问题也能友好提示,不会直接崩溃。
  • 可选优化:如果需要更实时的网络状态感知,不要每次点击才临时做DNS lookup,可以监听系统网络切换的系统广播,实时维护网络连接状态,比临时DNS查询响应更快、误判率更低。
修复后参考代码

网络检测方法

Future<bool> checkUserConnection() async {
  try {
    // 非阻塞延时300ms,给系统留网络状态切换的同步时间
    await Future.delayed(const Duration(milliseconds: 300));
    // 实际发邮件用的是smtp.gmail.com,直接检测该域名连通性更准确
    final result = await InternetAddress.lookup('smtp.gmail.com');
    final isConnected = result.isNotEmpty && result[0].rawAddress.isNotEmpty;
    setState(() {
      activeConnection = isConnected;
    });
    return isConnected;
  } on SocketException catch (_) {
    setState(() {
      activeConnection = false;
    });
    return false;
  }
}

点击触发逻辑

onTap: () async {
  // 等待检测完成,拿到最新的网络状态
  final isConnected = await checkUserConnection();
  if (isConnected) {
    try {
      await sendEmail();
      ScaffoldMessenger.of(context).showSnackBar(showSnackBar(
          false, "email sended ", Icons.check_circle));
    } on SocketException catch (_) {
      // 发送过程网络异常的兜底提示
      ScaffoldMessenger.of(context).showSnackBar(showSnackBar(
          true,
          "send failed, please check your internet connection",
          Icons.error_outline));
    }
  } else {
    ScaffoldMessenger.of(context).showSnackBar(showSnackBar(
        true,
        "check your internet connection !!!",
        Icons.error_outline));
  }
},

内容的提问来源于stack exchange,提问作者abr ahm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:18:16