1.2 二进制帧格式
Format
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
+---------------------------------------------------------------+
| Session Id (32) |
+---------------------------------------------------------------+
| timestamp ... |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| ... timestamp (64) |
+-+-+-+-----+-+-+-------+-------+-------------------------------+
|S|P|F| RSV |S|F| RSV |OPCODE | Payload len |
|T|A|R| (3) |L|I| (4) | (4) | (16) |
|R|C|A| |O|N| | | |
|E|K|G| |W| | | | |
+-+-+-+-----+-+-+-------+-------+-------------------------------+
| Stream Id (32) |
| (if STRE set to 1) |
+---------------------------------------------------------------+
| Packet Id (32) |
| (if PACK set to 1) |
+---------------------------------------------------------------+
| Fragment Id (32) |
| (if FRAG set to 1) |
+---------------------------------------------------------------+
: Payload Data ... :
+---------------------------------------------------------------+
Fields
Session Id: 4 bytes
唯一标识一个 session,由连接双方在握手阶段共同生成。客户端生成高 16 位,服务端生成低 16 位。客户端与服务端生成时分别采用无符号 16 位随机整数。
timestamp: 64 bits
发送当前帧时的时间戳,精确到毫秒。接收方收到该帧时,可知晓该帧于什么时间发出。由于客户端与服务端位于拓扑结构异常复杂的互联网环境中,所以双方的时间几乎肯定是不同步的,甚至误差较大,所以该时间戳只是用于粗略估计。
STRE: 1 bit
Stream 标记,如果设置表明当前帧通过 Stream 发送或接收,头部中有 Stream Id 字段标识所属 Stream
PACK: 1 bit
Packet 标记,如果设置表明当前帧是一个数据包,头部中有 Packet Id 字段标识所属 Packet
FRAG: 1 bit
Fragment 标记,如果设置表明当前帧是 Packet 中的一个分片,头部中有 Fragment Id 字段标识所属 Fragment
RSV: 3 bits
保留位,扩展协议时使用
SLOW: 1 bit
降速标记,接收数据包时,如果发送端发送速度过快,接收端接收缓存已满,在发送 ack 帧给发送端时可设置该标记,通知发送端降低发送速度。
FIN: 1 bit
最后一个分片标记,一旦 Packet 数据长度超过 MTU 就需要分片,在发送最后一个分片时,需要设置该标记,使得接收端得知分片数量并确定是否已接收全部分片。
RSV: 4 bits
保留位,扩展协议时使用
OPCODE: 4 bits
定义帧类型,不同类型的帧完成不同的功能,对所负载数据(Payload)的解释也不同。如果收到了未定义的 opcode,则该帧必须被丢弃。
%x0 (data) 二进制数据帧,携带二进制数据
%x1-3 保留的非控制帧
%x4 (ack) 确认数据已达帧
%x5 (ping) 心跳检测帧
%x6 (pong) 心跳应答帧
%x7 (openstream) 请求创建 Stream 帧
%x8 (streamopen) 创建 Stream 应答帧
%x9 (closestream) 请求关闭 Stream 帧
%xA (shakehand) 请求连接创建 Session 帧
%xB (handshake) 创建 Session 应答帧
%xC (goaway) 请求关闭 Session 帧
%xD-F 保留控制帧
Payload length: 2 bytes
2 字节无符号整数,当前帧负载数据(Payload)长度,应不超过 MTU 值。
Stream Id: 0 or 4 bytes
4 字节无符号整数,当设置 STRE 标记时,需要写入该字段标识当前数据包所属 Stream,如果未设置 STRE 标记,则该字段缺席。
Packet Id: 0 or 4 bytes
4 字节无符号整数,当设置 PACK 标记时,需要写入该字段标识当前数据包所属 Packet,如果未设置 PACK 标记,则该字段缺席。
Fragment Id: 0 or 4 bytes
4 字节无符号整数,当设置 FRAG 标记时,需要写入该字段标识当前数据包分片所属 Fragment,以及 Fragment 在所属 Packet 中的序号,如果未设置 FRAG 标记,则该字段缺席。
Payload Data: [Payload length] bytes
负载数据,数据长度由 payload length 字段定义