1 个不稳定版本
使用旧的 Rust 2015
0.2.1 | 2018年7月16日 |
---|---|
0.1.0 |
|
#57 在 #reliable
43KB
1K SLoC
可靠的 UDP
RUDP 在 UDP 之上构建了一些可靠性机制,可以在运行时根据需要添加,使其更像 TCP。
如果 TCP 太严格但 UDP 太宽松,那么 RUDP 可能会提供您需要的功能。
示例
Endpoint
结构封装了一些 UdpLike
对象,并使用一个状态包装器。此对象只需支持 send
和 recv
(不明确对等地址);UdpSocket 已经具有此功能。
// wrap a mio UdpSocket
let sock = mio::net::UdpSocket::bind(addr).unwrap();
sock.connect(peer_addr).unwrap();
let mut endpt = Endpoint::new(sock);
// write a single payload b"Hello, there.".
endpt.write(b"Hello").unwrap();
endpt.write(b", there.").unwrap();
endpt.send_written(Guarantee::Order).unwrap();
// Here's a more convenient form when all the data is in one place
endpt.send_payload(Guarantee::Delivery, b"General Kenobi!").unwrap();
// try to receive the next message. Returns `Ok(None)` if the inner UdpLike
// yields some `WouldBlock` error.
if let Some(msg) = endpt.recv().expect("fatal io error!") {
println!("msg {:?}", msg);
} else {
println!("Nothing ready yet!");
}
// Send three distinct payloads, but allow the peer to yield them
// in any order with respect to one another.
endpt.as_set(|mut s| {
endpt.send_payload(Guarantee::Delivery, b"A")?;
endpt.send_payload(Guarantee::None, b"B")?;
endpt.send_payload(Guarantee::Order, b"C")?;
}).unwrap();
// pass control flow to the endpoint so that it can still send heartbeats,
// clear old references and resend lost packets if you dont want to send or recv.
endpt.maintain();
特性
目前正在工作
- 具有类似栈的内部缓冲区,用于接收和发送存储,因此消息的复制很少。接收到的数据默认不复制,而是作为就地切片传递。
- 如果主缓冲区太满,则提供次要、临时的堆类似存储。
- 可选配置心跳周期、窗口大小、缓冲区大小等。
- 消息集语义,用于放松一组消息的顺序
- 三个层次的消息类别,确定保证
计划中
- 可选加密头部 + 非ce 字段以使连接更安全。
- 在底层自动将小型有效载荷组合成更大的 UDP 数据报。
- 端点服务器,用于在单个 UDP 端口上复用多个端点。
未计划
- 一些更高级的 TCP 机制,如背压控制和 AIMD。
- 自动线程执行底层的心跳。(这是故意的)。所有工作都是响应用户的显式调用而执行的。
管理连接
RUDP 连接由一个 Endpoint
结构维护,该结构基于任何 Udp-like 结构。((我们建议使用 mio::net::UdpSocket
)). 所有它的函数都分为三类
- 输出:
send_written
、io::write
、send_payload
、... - 输入:
recv
- 控制:
maintain
端点没有自己的控制线程,也不会无限期地执行其调用。通信的进展
依赖项
~2MB
~48K SLoC