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

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();
  }
}

额外注意事项:

  1. 编码依赖:Dart标准库没有Windows-1250编码,需要在pubspec.yaml添加依赖:
dependencies:
  charset_converter: ^1.0.0
  1. 发送逻辑:必须用socket.add()发送字节数组,write()是用于字符串传输的,不适合二进制协议。
  2. 空安全:全程对socket做空判断,避免空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:35:02