Flutter网络请求出现Connection reset by peer异常,求解决方案
开发了一款从互联网API获取数据的小型Flutter应用,正常运行无问题,但偶尔会失去网络连接,抛出如下异常:
E/flutter ( 3931): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Connection reset by peer
E/flutter ( 3931): #0 IOClient.send (package:http/src/io_client.dart:88:7)
E/flutter ( 3931): <asynchronous suspension>
E/flutter ( 3931): #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
E/flutter ( 3931): <asynchronous suspension>
E/flutter ( 3931): #2 _withClient (package:http/http.dart:164:12)
E/flutter ( 3931): <asynchronous suspension>
使用的是最新版本的http库,Flutter SDK版本为3.3.0,请求代码如下:
Future fetchMain() async { var response = await http.get(Uri.parse('https://************.php')); if (response.statusCode == 200) { final Data = json.decode(response.body).cast<Map<String, dynamic>>(); List<MainModel> ListData = Data.map<MainModel>( (json) { return MainModel.fromJson(json); }).toList(); return ListData; } else { } }
网络连接会断开约3分钟后自动恢复,请问该异常的成因是什么?如何解决?
- 服务器主动断连:服务器可能设置了较短的连接超时阈值,当连接闲置或请求响应超时,会主动重置TCP连接,触发该异常。
- 网络中间设备清理连接:路由器、防火墙或ISP的设备通常会对闲置TCP连接设置超时(时长多在3分钟左右,与描述的断开时间吻合),超时后直接中断连接。
- 客户端网络波动:设备临时丢失网络信号、切换网络时,TCP连接会被强制重置,后续请求无法正常发送。
添加异常捕获与重试机制
针对连接重置类异常设置自动重试逻辑,限制重试次数和间隔,避免无效请求。修改后的代码示例:import 'dart:convert'; import 'package:http/http.dart' as http; Future<List<MainModel>?> fetchMain() async { const int maxRetries = 3; const Duration retryDelay = Duration(seconds: 2); for (int i = 0; i < maxRetries; i++) { try { var response = await http.get(Uri.parse('https://************.php')); if (response.statusCode == 200) { final data = json.decode(response.body).cast<Map<String, dynamic>>(); List<MainModel> listData = data.map<MainModel>( (json) => MainModel.fromJson(json), ).toList(); return listData; } else { return null; } } catch (e) { if (e.toString().contains('Connection reset by peer') && i < maxRetries - 1) { await Future.delayed(retryDelay); continue; } rethrow; } } return null; }设置请求超时
给http请求添加超时限制,避免请求长时间挂起,超时后主动终止并触发重试:var response = await http.get(Uri.parse('https://************.php')) .timeout(const Duration(seconds: 10));监听网络状态(可选)
使用connectivity_plus库监听设备网络状态,检测到网络断开时暂停请求,恢复后再重新发起,减少异常触发概率。保持连接活跃(需服务器配合)
在请求头中添加Connection: keep-alive,同时定期发送轻量心跳请求,避免连接被中间设备判定为闲置状态。
内容的提问来源于stack exchange,提问作者M Al

