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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:45:32