7 个版本
0.2.1 | 2023年7月21日 |
---|---|
0.2.0 | 2020年6月29日 |
0.1.4 | 2018年3月26日 |
0.1.3 | 2016年11月13日 |
#5 in #环形
每月78次下载
在 2 crates 中使用
43KB
738 行
CircBuf
字节可增长环形缓冲区的实现。`CircBuf` 结构体管理在堆上分配的字节缓冲区。当需要时,缓冲区可以增长,并可以返回其内部缓冲区的切片,这些切片可以用于正常的 IO(`read` 和 `write`)以及矢量 IO(`readv` 和 `writev`)。
支持 `bytes`
如果启用了 `bytes` 功能标志,则 `bytes` crate 将作为依赖项添加,并为 `CircBuf` 实现了 `Buf` 和 `BufMut` 特性。实现了可选的矢量读写函数,允许您使用 `CircBuf` 进行高效的矢量 IO 操作,例如与 `tokio` 库一起使用。例如,查看 read_buf 和 write_buf 方法,当启用了 `bytes` 功能标志时,这些方法可以接受 `CircBuf`。
示例
以下是一个简单示例,其中服务器使用 `CircBuf` 从客户端读取消息。它使用 `vecio` crate 在套接字上调用 `readv`。消息由竖线 `|` 分隔,服务器返回它收到的每个消息的字节数。
extern crate vecio;
extern crate circbuf;
use std::thread;
use std::net::{TcpListener, TcpStream};
use std::io::Write;
use vecio::Rawv;
use circbuf::CircBuf;
fn handle_client(mut stream: TcpStream) {
let mut buf = CircBuf::new();
let mut num_messages = 0; // number of messages from the client
let mut num_bytes = 0; // number of bytes read since last '|'
loop {
// grow the buffer if it is less than half full
if buf.len() > buf.avail() {
buf.grow().unwrap();
}
let n;
{
n = match stream.readv(&buf.get_avail()) {
Ok(n) => {
if n == 0 {
// EOF
println!("client closed connection");
break;
}
n
}
Err(e) => panic!("got an error reading from a connection: {}", e),
};
}
println!("read {} bytes from the client", n);
// update write cursor
buf.advance_write(n);
// parse request from client for messages seperated by '|'
loop {
match buf.find_from_index(b'|', num_bytes) {
Some(i) => {
let response = format!("Message {} contained {} bytes\n", num_messages, num_bytes + i - 1); // don't include '|' in number of bytes
match stream.write(&response.as_bytes()) {
Ok(n) => {
println!("wrote {} bytes to the client", n);
// update read cursor past '|' and reset num_bytes since last '|'
buf.advance_read(i + 1);
num_bytes = 0;
num_messages += 1;
}
Err(e) => panic!("got an error writing to connection: {}", e),
}
}
None => break,
}
}
}
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8888").unwrap();
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || handle_client(stream));
}
Err(e) => panic!("got an error accepting connection: {}", e),
}
}
}
依赖项
~44KB