Flutter向Kotlin服务端用readUTF传输UTF-8数据失败问题排查
解决Flutter-Dart客户端与Kotlin服务端DataInputStream.readUTF兼容问题
问题核心在于Java的DataInputStream.readUTF()并非读取普通UTF-8字符串,它依赖一套专属的编码协议,对应Java中DataOutputStream.writeUTF()的格式:
- 先写入2字节大端无符号短整型,表示后续UTF-8字节的总长度
- 再写入字符串对应的UTF-8字节数据
之前直接用Dart的write()/writeln()发送字符串,只会输出纯UTF-8字节,缺少前置的长度标识,导致服务端readUTF()无法解析,只能用BufferedReader读取普通文本。
正确的Dart实现方式
手动实现符合Java规范的writeUTF逻辑,代码如下:
import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; // 模拟Java DataOutputStream.writeUTF的逻辑 void writeJavaUTF(Socket socket, String content) { List<int> utf8Bytes = utf8.encode(content); // Java writeUTF限制UTF-8字节数不超过65535 if (utf8Bytes.length > 65535) { throw ArgumentError('Content exceeds maximum length for Java readUTF'); } // 生成大端字节序的长度标识(2字节) Uint8List lengthPrefix = Uint8List(2); lengthPrefix[0] = (utf8Bytes.length >> 8) & 0xFF; lengthPrefix[1] = utf8Bytes.length & 0xFF; // 依次发送长度前缀和UTF-8字节 socket.add(lengthPrefix); socket.add(utf8Bytes); socket.flush(); }
使用示例
连接Socket后,调用该方法发送字符串:
Socket.connect('your-server-ip', port).then((socket) { // 发送符合Java readUTF格式的字符串 writeJavaUTF(socket, "后续二进制包的信息"); // 后续按原协议发送包大小、二进制数据(需保持与Java客户端一致的字节序) });
注意事项
- 后续发送包大小(原Java客户端用
writeInt())时,同样需要保证是4字节大端整型,Dart中可通过ByteData实现 - 确保整个传输流程的字节序、数据格式与原Kotlin/Java/C#客户端完全对齐,避免破坏现有兼容性
内容的提问来源于stack exchange,提问作者Emanuel
相关产品推荐
相关产品推荐

