5个不稳定版本
0.3.0 | 2024年7月28日 |
---|---|
0.2.1 | 2024年7月28日 |
0.2.0 | 2024年7月28日 |
0.1.1 | 2024年7月14日 |
0.1.0 | 2024年7月14日 |
#554 in 异步
每月515次下载
105KB
2K SLoC
libuio
一个高性能的Linux特定异步框架,基于io_uring
,支持零拷贝网络。
lib.rs
:
libuio
这是一个功能齐全的异步框架,旨在在Linux上运行,针对高性能网络解决方案进行了优化。其设计上本质上是多线程的,并在底层使用io_uring
作为I/O驱动程序。这使得相对于epoll、
poll和
select
等技术,实现了前所未有的效率提升。该包被拆分为几个模块,每个模块处理所需功能的一个特定子集。
有关详细示例,请参阅此存储库根目录下的examples目录。
从高层次来看,一个简单的TCP回声服务器按预期工作
use std::io;
use futures::StreamExt;
use libuio::net::TcpListener;
#[libuio::main]
async fn main() -> io::Result<()> {
// Since we are demonstrating a TCP server, lets start by creating a new TcpListener that
// is set to listen on [::]:9091 and have a connection backlog of 1024.
let mut listener = TcpListener::with_outstanding("[::]", 9091, 1024)?;
let mut buf = vec![0u8; 1024];
println!("Listening on: {}", listener.local_addr());
// Or we can grab a async stream of incoming connections, this is using the
// opcode::AcceptMulti, which is a highly efficient implementation of the standard accept
// loop. This will loop endlessly until dropped or there is an unrecoverable error.
//
// Note that you want to call incoming OUTSIDE of a loop like bellow, otherwise you will
// be implicitly droping/recrating the incoming future which results in performance worse
// than that of a a `listener.accept().await` loop would provide.
let mut incoming = listener.incoming();
while let Some(conn) = incoming.next().await {
let mut conn = match conn {
Ok(conn) => conn,
Err(e) => {
println!("Oh no we had an error: {}", e);
continue;
}
};
println!("Got connection from: {}", conn.peer_addr());
let read = match conn.recv(buf.as_mut_slice()).await {
Ok(ret) => ret,
Err(e) => {
println!("Failed to receive from client: {}", e);
continue;
}
};
let s = String::from_utf8_lossy(&buf[..read]);
println!("Client request: {}", s);
conn.send(&buf[..read])
.await
.expect("Failed to respond to client.");
}
Ok(())
}
同样,这里有一个与上述服务器交互的TCP客户端示例
use std::{io, net::SocketAddr};
use libuio::net::TcpStream;
#[libuio::main]
async fn main() -> io::Result<()> {
println!("Connecting to remote server.");
let remote_addr: SocketAddr = "[::1]:9091".parse().unwrap();
let mut client = TcpStream::new(false)?;
// Connect to the defined remote host.
client.connect(&remote_addr).await?;
println!(
"Connected to remote peer {}, local address: {}",
client.peer_addr(),
client.local_addr(),
);
// Send some data to the remote host.
client.send("Hello from client!".as_bytes()).await?;
// Now read back anything the server sent and then exit.
let mut buf = vec![0u8; 1024];
let read = client.recv(buf.as_mut_slice()).await?;
let str = String::from_utf8_lossy(&buf[..read]);
println!("Server response: {}", str);
Ok(())
}
如上述示例所示,这几乎可以直接替换std::net::TcpListener和std::net::TcpStream。
依赖项
~3.5MB
~67K SLoC