通过 tcp 读取时重用 BytesMut 缓冲区

问题描述 投票:0回答:1

我正在通过 tcp 阅读不同的消息,我的想法是避免将内容复制到内存并重用生成的缓冲区。

我下面显示的代码是我如何通过 tcp 读取的示例。首先,我读取包含要读取的总字节数的标头。然后我创建一个循环来填充设定大小的缓冲区,当达到这个大小时,我创建一条消息并将其发送到另一个线程。在此消息中,我必须执行 .to_vec() 因为我已经确定它是 Vec 类型。一旦它满了,我重置这个缓冲区以继续阅读。

AsyncReadExt

如果我将消息中的类型更改为 BytesMut,我会在该行中收到错误:

let mut n_bytes_read = 0; let mut chunk_id = 0; let mut last_chunk = false; // Get header let total_bytes = stream.read_u32().await.unwrap(); let mut reset = false; let mut buffer = BytesMut::with_capacity(config.send_buffer_capacity); let mut bytes_per_chunk = 0; loop { if reset { buffer = BytesMut::with_capacity(config.send_buffer_capacity); reset = false; } match stream.read_buf(&mut buffer).await { Ok(0) => { continue; } Ok(n) => { bytes_per_chunk += n; n_bytes_read += n; if n_bytes_read == total_bytes.try_into().unwrap() { last_chunk = true; } if bytes_per_chunk == config.send_buffer_capacity || last_chunk{ let message = Message::new( id, client_id, ClientOperation::Send, chunk_id, last_chunk, total_bytes, buffer.to_vec(), ); //println!("message: {:?}", message); queue.push(message); chunk_id += 1; bytes_per_chunk = 0; reset = true; } if last_chunk { break; } } Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => { //debug!("Err: TCP -> SV (Write))"); continue; } Err(e) => { return Err(e.into()); } } }

如下:

match stream.read_buf(&mut buffer).await {

如果我对缓冲区执行
let mut buffer = BytesMut::with_capacity(config.send_buffer_capacity); | ---------- move occurs because `buffer` has type `BytesMut`, which does not implement the `Copy` trait ... 402 | loop { | ---- inside of this loop ... 405 | buffer = BytesMut::with_capacity(config.send_buffer_capacity); | ------ this reinitialization might get skipped ... 409 | match stream.read_buf(&mut buffer).await { | ^^^^^^^^^^^ value borrowed here after move ... 430 | buffer, | ------ value moved here, in previous iteration of loop

,它将执行与执行

.clone()
相同的操作,它将复制内存。
然后我必须重置不正常的缓冲区,但什么也不起作用。

我尝试使用

.to_vec()

方法,但它从未写入缓冲区。

有什么方法可以让缓冲区保留在内存中,并且我可以在消息中传递引用吗?并且仍然使用缓冲区继续读取?

rust tcp byte
1个回答
0
投票
read_exact()

而不是跟踪何时并在下一次迭代中执行,则可以避免最简单的问题解决方案。所以从这个最小的复制器开始吧

buffer

对此:

struct Foo; fn main() { let mut reset = false; let mut buffer = Foo; loop { if reset { buffer = Foo; } let _message = (buffer,); reset = true; } }

© www.soinside.com 2019 - 2024. All rights reserved.