You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.6 KiB
3.6 KiB
mKCP 协议
mKCP 是流式传输协议,由 KCP 协议 修改而来,可以按顺序传输任意的数据流。
版本
mKCP 没有版本号,不保证版本之间兼容性。
依赖
底层协议
mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。
函数
- fnv: FNV-1a 哈希函数
- 输入参数为任意长度的字符串;
- 输入出一个 32 位无符号整数;
通讯过程
- mKCP 将数据流拆成若干个数据包进行发送。一个数据流有一个唯一标识,用以区分不同的数据流。数据流中的每一个数据包都携带了同样的标识。
- mKCP 没有握手过程,当收到一个数据包时,根据其携带的数据流的标识来判断是否为新的通话,或是正在进行中的通话。
- 每一个数据包中包含若干个片段(Segment),片段分为三类:数据(Data)、确认(ACK)、心跳(Ping)。每个片段需要单独处理。
数据格式
数据包
4 字节 | 2 字节 | L 字节 |
---|---|---|
认证信息 A | 数据长度 L | 片段部分 |
其中:
- 认证信息 A = fnv(片段部分),big endian;
- 片段部分可能包含多个片段;
数据片段
2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 | 2 字节 | Len 字节 |
---|---|---|---|---|---|---|---|
标识 Conv | 指令 Cmd | 选项 Opt | 时间戳 Ts | 序列号 Sn | 未确认序列号 Una | 长度 Len | 数据 |
其中:
- 标识 Conv: mKCP 数据流的标识
- 指令 Cmd: 常量 0x01
- 选项 Opt: 可选的值有:
- 0x00: 空选项
- 0x01: 对方已发出所有数据
- 时间戳 Ts: 当前片段从远端发送出来时的时间,big endian
- 序列号 Sn: 该数据片段时数据流中的位置,起始片段的序列号为 0,之后每个新片段按顺序加 1
- 未确认序列号 Una: 远端主机正在发送的,且尚未收到确认的最小的 Sn
确认片段
2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 | 2 字节 | Len * 4 字节 |
---|---|---|---|---|---|---|---|
标识 Conv | 指令 Cmd | 选项 Opt | 窗口 Wnd | 下一接收序列号 Sn | 时间戳 Ts | 长度 Len | 已收到的序列号 |
其中:
- 标识 Conv: mKCP 数据流的标识
- 指令 Cmd: 常量 0x00
- 选项 Opt: 同上
- 窗口 Wnd: 远端主机可以接收的最大序列号
- 下一接收序列号 Sn: 远端主机未收到的数据片段中的最小序列号
- 时间戳 Ts: 远端主机最新收到的数据片段的时间戳,可用于计算延迟
- 已收到的序列号: 每个 4 字节,表示此序列号的数据已经确认收到
注释:
- 远程主机期待收到序列号 [Sn, Wnd) 范围内的数据
心跳片段
2 字节 | 1 字节 | 1 字节 | 4 字节 | 4 字节 | 4 字节 |
---|---|---|---|---|---|
标识 Conv | 指令 Cmd | 选项 Opt | 未确认序列号 Una | 下一接收序列号 Sn | 延迟 Rto |
其中:
- 标识 Conv: mKCP 数据流的标识
- 指令 Cmd: 可选的值有
- 0x02: 远端主机强行终止会话
- 0x03: 正常心跳
- 选项 Opt: 同上
- 未确认序列号 Una: 同数据片段的 Una
- 下一接收序列号 Sn: 同确认片段的 Sn
- 延迟 Rto: 远端主机自己计算出的延迟