外观
TCP 为什么有粘包 半包 怎样解析?
标准回答
TCP 提供有序字节流,不保留应用每次 write 的消息边界。一次 read 可能只读到半条业务消息,也可能读到多条消息拼在一起。应用必须自定义边界,例如固定长度、分隔符或长度字段。(RFC 9293 TCP 规范)
机制解释
长度字段方案可以在消息头写入 payload 长度,先读足头部,校验长度,再读足正文。必须限制最大长度,并处理 EOF、超时和非法格式,避免根据不可信长度无限申请内存。
**代码练习四 读取长度前缀消息:**示例约定 4 字节大端有符号长度,正文上限 1MiB;在后台 I/O 执行。真实协议还需要业务类型、版本、序号与必要的完整性验证。
java
static byte[] readFrame(DataInputStream in) throws IOException {
int length = in.readInt();
if (length < 0 || length > 1024 * 1024) {
throw new IOException("Invalid frame length");
}
byte[] body = new byte[length];
in.readFully(body);
return body;
}延伸追问
读取中间超时后继续调 readFrame 吗?这个简化实现不能安全地从头恢复。若已读了一部分,必须保留解析状态继续,或关闭连接重新建立边界。还要设整帧总期限,避免对端每次少发几个字节却永不完成。
内容来源
- Android 智能硬件 SDK 技术 Wiki · 原条目
Q48