Flutter中TCP Socket通信异常:无法接收设备返回数据求助
TCP Socket Flutter代码无法接收设备响应的问题排查
我通过TCP Socket连接设备、写入数据并读取响应的功能已用C#实现且正常运行,C#代码如下:
using (TcpClient client = new TcpClient(terminal.server_IP, terminal.port)) { try { using (NetworkStream stream = client.GetStream()) { try { stream.ReadTimeout = 5000; byte[] msg = new byte[10]; msg[0] = 1; msg[1] = 1; msg[2] = 0; msg[3] = 5; msg[4] = 70; msg[5] = 82; msg[6] = 82; msg[7] = 84; msg[8] = 67; msg[9] = 81; stream.Write(msg, 0, msg.Length); int i = 0; while (!stream.DataAvailable && i < 5) { await Task.Delay(100); i++; } byte[] data = new byte[4096]; int bytes = stream.Read(data, 0, data.Length); msg = new byte[bytes]; string tst = Encoding.GetEncoding("Windows-1250").GetString(data, 2, data[1]); } finally { stream.Close(); } } } finally { client.Close(); } }
现转成Flutter代码后无报错,但无法接收设备返回的数据,Flutter代码如下:
try { socket?.destroy(); socket = await Socket.connect(serverIP, serverPort).catchError((error) { print('error $e'); }); socket!.listen((data) { print('data'); }, onError: (e) { print('error'); socket!.destroy(); }, onDone: () { print('done'); socket!.destroy(); }, cancelOnError: false); List<int> message = [1, 1, 0, 5, 70, 82, 82, 84, 67, 81]; socket!.write(message); } catch (e) { print('errors: $e'); }
问题出在这几个地方:
- 发送数据的方式错误:Flutter的
Socket.write()传入List<int>时,会把每个整数转成对应字符再发送,不是直接发送原始字节流。设备收到的请求格式和C#发送的不一样,自然不会返回响应。 - 缺少编码处理逻辑:C#里用
Windows-1250编码解析响应,Flutter代码完全没做这部分处理,就算收到数据也无法正确解析。 - 错误处理不严谨:
catchError里打印的$e未定义,而且没有确保socket的空安全处理。
修正后的Flutter代码:
import 'dart:io'; import 'package:charset_converter/charset_converter.dart'; Future<void> connectToDevice(String serverIP, int serverPort) async { Socket? socket; try { // 清理旧连接 socket?.destroy(); // 建立TCP连接 socket = await Socket.connect(serverIP, serverPort); print('设备连接成功'); // 构造要发送的原始字节数据 final List<int> message = [1, 1, 0, 5, 70, 82, 82, 84, 67, 81]; // 用add发送原始字节,和C#的stream.Write行为一致 socket.add(message); // 强制刷新缓冲区,确保数据发送出去 await socket.flush(); // 监听设备响应 socket.listen( (data) { // 按照C#的逻辑解析响应:从索引2开始,取data[1]长度的字节 if (data.length >= 2) { final int responseLength = data[1]; if (2 + responseLength <= data.length) { // 用Windows-1250编码解析字节 CharsetConverter.decode("windows-1250", data.sublist(2, 2 + responseLength)) .then((decodedStr) => print('解析后的响应:$decodedStr')); print('原始响应字节:$data'); } } }, onError: (error) { print('监听错误:$error'); socket?.destroy(); }, onDone: () { print('连接已关闭'); socket?.destroy(); }, cancelOnError: false, ); // 模拟C#的等待逻辑,给设备一点响应时间 await Future.delayed(const Duration(milliseconds: 500)); } catch (e) { print('连接/通信错误:$e'); socket?.destroy(); } }
额外注意事项:
- 编码依赖:Dart标准库没有
Windows-1250编码,需要在pubspec.yaml添加依赖:
dependencies: charset_converter: ^1.0.0
- 发送逻辑:必须用
socket.add()发送字节数组,write()是用于字符串传输的,不适合二进制协议。 - 空安全:全程对socket做空判断,避免空指针异常。
内容的提问来源于stack exchange,提问作者Taliga
相关产品推荐
相关产品推荐

