2 releases

Uses new Rust 2024

new 0.1.1 Apr 30, 2025
0.1.0 Apr 30, 2025

#875 in Network programming

MIT license

49KB
1.5K SLoC

muxing 多路复用协议

可以在TCP, KCP, Websocket二进制流上构建出多路复用

帧处理

在底层使用流式连接,但在其上增加了消息帧处理,从而可在多逻辑流之间共享连接。每个帧包含如下头部:

  • 版本 (8 位)
  • 标志 (8 位)
  • 保留字段 (16 位),RST中会在这字段写入错误码
  • 流ID (32 位)
  • 长度 (32 位)

这意味着每个头部有 12 字节的开销。
所有字段均采用网络字节序(大端序)编码。
以下是各字段的详细描述:

版本字段

版本字段用于未来的向后兼容。目前,该字段始终设置为 0,以表示初始版本。

标志字段

标志字段用于提供与消息类型相关的额外信息。支持以下标志:

  • 0x1 SYN - 表示新流的起始。可与数据一同发出,如Request请求。
  • 0x2 ACK - 确认新流的启动。对端第一次响应写数据时确认 ACK
  • 0x4 FIN - 对流执行半关闭。可与数据消息一起发送。发起端发送FIN标记后不能再发数帧数据
  • 0x8 RST - 立即重置流。

流ID字段

流ID字段用于标识帧所针对的逻辑流。客户端应使用奇数 ID,而服务器则使用偶数 ID,以避免冲突。另外,流ID 0 被保留用于表示整个会话。

长度字段

长度字段的含义取决于消息的类型:

  • 数据 - 指示紧随头部后的字节数
  • 最大的数据长度需随服务端与服务端约定,默认8K。

消息流程

没有明确的连接建立过程;它依赖底层传输机制。然而,会话中存在客户端与服务器的区别。

打开流

要打开一个流,首先发送带有新流ID的数据或窗口更新帧,并设置 SYN 标志以表示新流的建立。

接收方必须随后回复一个带有相同流ID和 ACK 标志的帧,或者回复一个带有 RST 标志的帧以拒绝该流。

由于依赖于底层的可靠传输,发送方在发送带有 SYN 标志的帧后即可开始传输数据,无需等待 ACK。这在需要立即发送请求而不等待 RTT 的 RPC 系统中尤其适用。

这也意味着在数据发送后,连接可能会被拒绝。这与 TCP 略有不同,因为在 TCP 中连接一旦建立就不会被拒绝。客户端应准备好处理接收到的 RST 错误。

关闭流

要关闭一个流,任一方发送带有 FIN 标志的帧,表示对流进行半关闭,即发送方不再传输数据。

当双方都完成关闭操作后,该流即被关闭。

或者,在发生错误时,可使用 RST 标志立即强行关闭流。 发送RST标记时,在保留字段写入 【错误码】

流量控制

每个帧都有最大的数据长度限制默认为256KB

会话终止

当会话即将终止时,从底层连接(如:Websocket的Close帧)进行关闭,分流协议不提供优雅关闭,很多底程协议都以实现,没必要增加

错误码

0x0 标准关闭 0x1 协议错误 0x2 内部错误

Dependencies

~2–8MB
~57K SLoC