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

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日

悬赏问题

  • ¥15 ios可以实现ymodem-1k协议 1024字节传输吗?
  • ¥300 寻抓云闪付tn组成网页付款链接
  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)