1 个稳定版本
1.0.0 | 2024年1月12日 |
---|
#685 在 Rust 模式
12,936 每月下载量
在 19 个 crate 中使用 (通过 interprocess)
125KB
2.5K SLoC
recvmsg
用于可靠接收数据报,防止截断的 trait。
问题
与字节流接口不同,数据报套接字(尤其是 UDP)和其他基于分组的 API 保留了不同写入调用之间的边界,这就是“消息边界”的基本含义。通过部分读取提取消息是一项错误率高的任务,这也是为什么没有任何操作系统暴露此类接口的原因——相反,来自消息 IPC 通道的所有消息都是完整的消息,而不是消息片段,这在很大程度上简化了事情,并且可以说是实现数据报支持的唯一正确方式。
与此设计相关的一个特点是:不能仅使用任意长度的缓冲区成功接收消息。对于字节流,这始终有效——要么缓冲区中有可以写入的数据,要么已达到文件末尾,除了隐含的错误情况,这对于任何类型的 I/O 总是存在的可能性。然而,对于数据报而言,缓冲区中可能并不总是有足够的空间来获取整个消息。如果缓冲区太小无法获取消息的一部分,它会被截断,消息最终会变成基本不规则的。
解决方案
RecvMsg
trait(及其异步对应物,AsyncRecvMsg
)提供了一个完全防止截断的接口。
通过使用 MsgBuf
,可以提供一个借用缓冲区,该缓冲区还可以根据需要随后转换为拥有缓冲区。或者,MsgBuf
可以从已经拥有的缓冲区开始。然后,内部 Vec
将根据需要调整大小,并可选择设置配额以防止连接耗尽所有内存。
实现
标准截断消息接收可以提供三种特性,以帮助程序解决截断问题:窥视、截断报告和精确长度查询。前两种特性由TruncatingRecvMsg
特质表示,而最后一种可以视为这些特性的扩展,因此作为TruncatingRecvMsgWithFullSize
提供。这两个都有异步对应版本。
RecvMsg
或AsyncRecvMsg
将通过实现这些特质之一,并使用相应模块中的辅助函数来实施。
功能标志
std
– 当QuotaExceeded
时,使用std::error::Error
。排除了#![no_std]
。std_net
– 在Unix上,使用来自std::net
和std::os::unix::net
(Unix域套接字)的类型实现的特质。
依赖项
~0–12MB
~90K SLoC