#message #datagram #traits #buffer #receiving #error #udp

无 std recvmsg

用于可靠接收数据报,防止截断的 trait

1 个稳定版本

1.0.0 2024年1月12日

#685Rust 模式

Download history 6/week @ 2024-03-14 37/week @ 2024-03-28 6/week @ 2024-04-04 9/week @ 2024-04-11 14/week @ 2024-04-18 68/week @ 2024-04-25 1570/week @ 2024-05-02 1864/week @ 2024-05-09 1919/week @ 2024-05-16 2271/week @ 2024-05-23 1769/week @ 2024-05-30 2229/week @ 2024-06-06 3460/week @ 2024-06-13 3837/week @ 2024-06-20 3127/week @ 2024-06-27

12,936 每月下载量
19 个 crate 中使用 (通过 interprocess)

0BSD 许可证

125KB
2.5K SLoC

recvmsg

Rust version: 1.60+

用于可靠接收数据报,防止截断的 trait。

问题

与字节流接口不同,数据报套接字(尤其是 UDP)和其他基于分组的 API 保留了不同写入调用之间的边界,这就是“消息边界”的基本含义。通过部分读取提取消息是一项错误率高的任务,这也是为什么没有任何操作系统暴露此类接口的原因——相反,来自消息 IPC 通道的所有消息都是完整的消息,而不是消息片段,这在很大程度上简化了事情,并且可以说是实现数据报支持的唯一正确方式。

与此设计相关的一个特点是:不能仅使用任意长度的缓冲区成功接收消息。对于字节流,这始终有效——要么缓冲区中有可以写入的数据,要么已达到文件末尾,除了隐含的错误情况,这对于任何类型的 I/O 总是存在的可能性。然而,对于数据报而言,缓冲区中可能并不总是有足够的空间来获取整个消息。如果缓冲区太小无法获取消息的一部分,它会被截断,消息最终会变成基本不规则的。

解决方案

RecvMsg trait(及其异步对应物,AsyncRecvMsg)提供了一个完全防止截断的接口。

通过使用 MsgBuf,可以提供一个借用缓冲区,该缓冲区还可以根据需要随后转换为拥有缓冲区。或者,MsgBuf 可以从已经拥有的缓冲区开始。然后,内部 Vec 将根据需要调整大小,并可选择设置配额以防止连接耗尽所有内存。

实现

标准截断消息接收可以提供三种特性,以帮助程序解决截断问题:窥视、截断报告和精确长度查询。前两种特性由TruncatingRecvMsg特质表示,而最后一种可以视为这些特性的扩展,因此作为TruncatingRecvMsgWithFullSize提供。这两个都有异步对应版本。

RecvMsgAsyncRecvMsg将通过实现这些特质之一,并使用相应模块中的辅助函数来实施。

功能标志

  • std – 当QuotaExceeded时,使用std::error::Error。排除了#![no_std]
  • std_net – 在Unix上,使用来自std::netstd::os::unix::net(Unix域套接字)的类型实现的特质。

依赖项

~0–12MB
~90K SLoC