如何在Dart中接收并解析Python Socket服务器发送的数据?
解决Python Socket服务器与Dart客户端的字节长度解析问题
解决方法
有两种可行方案,任选其一即可:
方案1:修改Python服务器代码,使用网络字节序打包长度
Python的struct.pack('Q', ...)默认使用主机字节序(多数x86/AMD64系统为小端序),改成网络标准的大端序打包,就能让Dart客户端用默认方式正确解析:
import struct # 用!Q表示网络字节序的无符号64位整数 length_bytes = struct.pack('!Q', len(pickle_dump)) # 拼接长度和数据后发送 socket.sendall(length_bytes + pickle_dump)
方案2:修改Dart客户端代码,用小端序解析长度
保持Python代码不变,在Dart中解析前8字节时指定小端序:
import 'dart:io'; import 'dart:typed_data'; void main() async { Socket socket = await Socket.connect('your_server_ip', your_port); // 先读取前8字节的长度数据 Uint8List lengthBytes = Uint8List(8); await socket.listen((data) { // 假设已完整读取8字节到lengthBytes ByteData byteData = ByteData.sublistView(lengthBytes); // 指定小端序解析无符号64位整数 int messageLength = byteData.getUint64(0, Endian.little); print('正确的消息长度:$messageLength'); }).asFuture(); }
原理说明
问题根源是字节序不匹配:
- Python的
struct.pack('Q', num):Q代表无符号64位整数,但默认采用主机字节序(取决于操作系统,x86/AMD64架构普遍是小端序,即低字节在前)。 - Dart的
ByteData.getUint64()默认采用大端序(网络字节序):这是网络通信的通用标准,要求高字节在前,和Python的默认打包方式正好相反。 - 字节序颠倒后,解析出的数值完全混乱:你得到的负数,本质是把小端序的字节按大端解析后,得到的无符号数超过了有符号64位整数的最大值(2^63-1),从而被显示为负数形式。
- Python客户端能正常解析,是因为
struct.unpack('Q', ...)同样使用主机字节序,和打包逻辑一致,自然不会出错。
内容的提问来源于stack exchange,提问作者Broteen Das
相关产品推荐
相关产品推荐

