大白金星 2023-03-07 15:30 采纳率: 100%
浏览 83
已结题

flutter开发TCP客户端时,收不到服务端发送的数据

问题:flutter开发TCP客户端时,收不到服务端发送的数据,主要表现为 if (buff.length >= totalLen) 这条判断无法执行,导致运行不到 onData!(this, cmd);所以,客户端收不到服务端的数据。而且我看网上接收socket消息时都是这么处理的,所以不知道怎么处理了(如果有flutter开发TCP的源码可以提供就更感谢了,最好是源码)

部分代码:

  _onData(Uint8List event) async {
    debugPrint('----------> $event  type=${event.runtimeType}');
    // buff = event;
    buff += event;
    print("TCP客户端接收到的数据是:${buff}");
    debugPrint('当前的缓冲区长度为: ${buff.length}');

    while (buff.length > 2) {
      int packLen = 0;
      List<int> lenBuf = buff.sublist(0, 2);
      Uint8List tmp = Uint8List.fromList(lenBuf);
      ByteData tmpByteData = ByteData.sublistView(tmp);
      packLen = tmpByteData.getUint16(0);

      debugPrint('lenBuf长度: $lenBuf');
      debugPrint('packLen长度: $packLen');

      var totalLen = packLen + 2;
      debugPrint('totalLen长度: $totalLen');

      if (buff.length >= totalLen) {
        List<int> curFrame = buff.sublist(2, totalLen);
        List<int> packed = buff.sublist(2, 2 + packLen);

        debugPrint("数据满足条件 ${buff.length}");
        buff.replaceRange(0, totalLen, []);

        debugPrint("json解码数据长度 ${packed.length}");
        var decoded = utf8.decode(packed);
        String cmd = jsonDecode(decoded);
        debugPrint("json------------>  data= $cmd");
        onData!(this, cmd);

        debugPrint("数据剩余长度 ${buff.length}");
      } else {
        debugPrint("数据长度不足 ${buff.length}");
        break;
      }
    }
  }

debug页面:
I/flutter (24579): ----------> [49, 50, 49, 50, 49, 50, 49, 50] type=Uint8List
I/flutter (24579): TCP客户端接收到的数据是:[49, 50, 49, 50, 49, 50, 49, 50, 49, 50, 49, 50, 49, 50, 49, 50]
I/flutter (24579): 当前的缓冲区长度为: 16
I/flutter (24579): lenBuf长度: [49, 50]
I/flutter (24579): packLen长度: 12594
I/flutter (24579): totalLen长度: 12596
I/flutter (24579): 数据长度不足 16


如果取消判断限制,则提示:
E/flutter (24579): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: RangeError (end): Invalid value: Not in inclusive range 2..8: 12596
E/flutter (24579): #0 RangeError.checkValidRange (dart:core/errors.dart:363:9)
E/flutter (24579): #1 List.sublist (dart:core-patch/growable_array.dart:84:38)
E/flutter (24579): #2 SocketClient._onData (package:tcpsocket/tcpsocket.dart:170:35)
E/flutter (24579): #3 SocketClient.connect.. (package:tcpsocket/tcpsocket.dart:89:9)


如果持续累加,知道判断条件满足,同样会报上述错误


编译环境:Android studio

  • 写回答

6条回答 默认 最新

  • 极客智能体-在线 2023-03-07 17:43
    关注

    以下答案由GPT-3.5大模型与博主波罗歌共同编写:
    有以下几种可能导致接收不到服务端发送的数据:

    1. TCP连接是否建立成功

    在客户端连接服务端之前需要检查TCP连接是否建立成功,如果连接失败则无法接收服务端发送的数据。

    1. 数据是否被粘包

    客户端可能会一次性接收到多个数据包,这些数据会被放到缓冲区中,如果没有将数据解析出来就会导致粘包问题。

    1. 数据长度判断错误

    在判断数据包长度的时候,如果判断条件不正确也会导致无法接收服务端发送的数据。

    根据你提供的代码,可能存在以下问题:

    1. 可能存在粘包问题,客户端可能会一次性接收到多个数据包,这些数据会被放到缓冲区中,在处理缓冲区中的数据时需要考虑到这个问题。

    2. 对于UTF-8编码的字符串的解析需要使用dart:utf包中的utf8.decode方法,否则可能导致解析失败。

    下面提供一份flutter开发TCP客户端的参考代码,仅供参考:

    import 'dart:convert';
    import 'dart:io';
    import 'dart:typed_data';
    
    typedef OnDataCallback = void Function(Uint8List);
    
    class TcpClient {
      String host;
      int port;
      Socket? _socket;
      OnDataCallback? onData;
    
      TcpClient({
        required this.host,
        required this.port,
        this.onData,
      });
    
      Future<void> connect() async {
        try {
          _socket = await Socket.connect(
            host,
            port,
          );
          _socket!.listen(_receive);
    
          print('Connected to: ${_socket!.remoteAddress.address}:${_socket!.remotePort}');
        } on IOException catch (e) {
          print('Error: ${e.toString()}');
        }
      }
    
      void _receive(Uint8List event) {
        if (onData != null) {
          onData!(event);
        }
      }
    
      void send(List<int> data) {
        if (_socket != null && _socket!.write(data) == null) {
          print('Error sending data');
        }
      }
    
      void close() {
        if (_socket != null) {
          _socket!.close();
        }
      }
    }
    

    在使用该代码进行测试时,可以使用如下方式测试:

    final client = TcpClient(
      host: '192.168.0.1',
      port: 2323,
      onData: (data) {
        final receivedMessage = Utf8Decoder().convert(data);
        print('Received: $receivedMessage');
      },
    );
    
    await client.connect();
    
    const message = 'Hello, world!\r\n';
    client.send(Utf8Encoder().convert(message));
    
    // Close the connection after 5 seconds
    await Future.delayed(Duration(seconds: 5));
    client.close();
    

    当然,以上代码仅仅是一份参考代码,实际上还需要根据具体情况进行异常处理、数据解析等等。如果你还有疑问,可以提出具体问题,我将在我的能力范围内为你解答。
    如果我的回答解决了您的问题,请采纳!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 3月16日
  • 已采纳回答 3月8日
  • 创建了问题 3月7日

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装