0.4.0 |
|
---|---|
0.3.0 |
|
#6 in #mux
42KB
1K SLoC
smux
一个轻量级的异步 smux (简单多路复用) 库,用于 Rust。
async-smux
消费一个实现 AsyncRead + AsyncWrite + Unpin + Send
的结构体,如 TcpStream
和 TlsStream
,以创建一个 Mux<T>
结构体。然后你可以在 Mux<T>
上启动多个 MuxStream<T>
(最多 4294967295 个),它也实现了 AsyncRead + AsyncWrite + Unpin + Send
。
基准测试
以下是在我的本地机器上进行的简单基准测试结果,与原始版本 smux(用 go 编写)进行比较。
实现 | 吞吐量(TCP) | 握手 |
---|---|---|
smux(go) | 0.4854 GiB/s | 17.070 K/s |
async-smux(rust) | 1.0550 GiB/s | 81.774 K/s |
运行 cargo bench
以自行测试。有关更多详细信息,请查看 /benches
目录。
惰性
此库不会启动任何线程或任务。它只是启动几个 future
。因此,它与运行时完全独立。
Mux
和 MuxStream
完全惰性,如果你不调用 poll()
,它们将什么也不做。
任何轮询操作,包括 .read()
,.write()
,accept()
和 connect()
,都将推动 Mux
和 MuxStream
的工作。
规范
VERSION(1B) | CMD(1B) | LENGTH(2B) | STREAMID(4B) | DATA(LENGTH)
VERSION: 1
CMD:
SYN(0)
FIN(1)
PSH(2)
NOP(3)
STREAMID: Randomly chosen number
示例
use async_smux::{Mux, MuxConfig};
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;
async fn echo_server() {
let listener = TcpListener::bind("0.0.0.0:12345").await.unwrap();
let (stream, _) = listener.accept().await.unwrap();
let mux = Mux::new(stream, MuxConfig::default());
loop {
let mut mux_stream = mux.accept().await.unwrap();
let mut buf = [0u8; 1024];
let size = mux_stream.read(&mut buf).await.unwrap();
mux_stream.write(&buf[..size]).await.unwrap();
}
}
fn main() {
async_std::task::spawn(echo_server());
async_std::task::block_on(async {
smol::Timer::after(std::time::Duration::from_secs(1)).await;
let stream = TcpStream::connect("127.0.0.1:12345").await.unwrap();
let mux = Mux::new(stream, MuxConfig::default());
for i in 0..100 {
let mut mux_stream = mux.connect().await.unwrap();
let mut buf = [0u8; 1024];
mux_stream.write(b"hello").await.unwrap();
let size = mux_stream.read(&mut buf).await.unwrap();
let reply = String::from_utf8(buf[..size].to_vec()).unwrap();
println!("{}: {}", i, reply);
}
});
}
依赖关系
~3.5–5.5MB
~94K SLoC