传输帧规范
本文档定义 KnotLink 协议在 TCP 链路上的 二进制帧结构。帧头负责定界和版本识别,消息体使用 KLUDF 格式(详见 消息体规范)。
帧结构
每帧由一个 8 字节定长帧头 和一个 变长消息体 组成,大端序(Big Endian):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Magic (2) | Version (2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Payload (变长) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 偏移 | 字段 | 大小 | 类型 | 值 | 说明 |
|---|---|---|---|---|---|
| 0 | Magic | 2 字节 | uint16 | 0x4B4B | 魔数,固定值 "KK"(ASCII),用于识别 KnotLink 帧 |
| 2 | Version | 2 字节 | uint16 | 0x0002 | 协议版本号,接收端校验不匹配时告警 |
| 4 | Length | 4 字节 | uint32 | 1 ~ 16,777,215 | Payload 的字节数,不含帧头。最大 16 MB |
| 8 | Payload | 变长 | — | — | 消息体,KLUDF 键值对格式 |
字段说明
Magic(魔数)
固定值 0x4B4B。两个字节的 ASCII 恰好是 "KK"(KnotLink)。
作用:快速识别 TCP 流中的 KnotLink 帧。接收端读到前两个字节不是 0x4B4B 时,说明对端不是 KnotLink 节点或数据已错位,应立即断开。
Version(协议版本)
当前版本 0x0002。
接收端校验规则:与自身支持版本不一致时告警但不拒绝。这是刻意设计——小版本升级不应导致存量节点不可用。若未来引入不兼容变更,会递增主版本号并通过 Magic 扩展机制区分。
Length(消息体长度)
Payload 的字节数,不含 8 字节帧头。最大 16 MB(16 × 1024 × 1024)。
发送端:先将消息体序列化为 UTF-8 字节串,计算长度,写入此字段。接收端:读 8 字节帧头 → 取 Length → 继续读取 Length 字节 → 得到一帧。
读写流程
发送端
1. 序列化消息体(KLUDF 键值对 → UTF-8 字节)
2. 写入 Magic: 0x4B4B (2 字节)
3. 写入 Version: 0x0002 (2 字节)
4. 写入 Length: 消息体字节数 (4 字节,大端)
5. 写入 Payload: 消息体字节
6. 通过 TCP socket 发送整帧
接收端
1. 读取 8 字节帧头
2. 校验 Magic 是否为 0x4B4B → 不是则断开
3. 校验 Version 是否匹配 → 不匹配则告警
4. 读取 Length(大端)
5. 读取 Length 字节 → 得到 Payload
6. Payload 反序列化为 KLUDF 键值对 → 交给上层处理
7. 回到第 1 步,读取下一帧
设计考量
为什么不用分隔符。常见的文本协议用 \n 或 \r\n 定界,但 KLUDF 消息体本身是纯文本,可能包含任意字符。用分隔符需要转义,增加解析复杂度。定长帧头 + 长度字段是二进制协议的标准做法,解析只需按偏移读整数,简单且高效。
为什么 16MB 上限。桌面应用间的消息通常是短小的指令或数据片段。16MB 覆盖了绝大多数场景(传一段日志、一个小文件),同时防止恶意或异常节点耗尽内存。
为什么大端序。大端(网络字节序)是 TCP/IP 世界的惯例,跨平台兼容性最好。所有 KnotLink SDK 的实现均使用大端序。
与协议分层的关系
| 层 | 本规范的定位 |
|---|---|
| ① 传输层 | TCP 提供字节流,帧结构在 TCP 之上定界 |
| ② 消息体层 | Payload 使用 KLUDF 格式,帧头不关心 Payload 内容 |
帧结构是 ① 和 ② 之间的粘合层——TCP 只负责传字节,帧结构告诉接收端"一条消息从哪里开始、到哪里结束"。
协议分层的完整说明见 协议分层。