gpt4 book ai didi

sockets - 在 BufReader 中包装后无法从底层读取器读取数据

转载 作者:可可西里 更新时间:2023-11-01 02:57:38 26 4
gpt4 key购买 nike

我的意图是访问 TcpStream 并在将 TcpStream 作为属性保存的结构的两种不同方法中执行两次读取操作。

第一个操作执行良好,但是当我尝试在第二个方法上加载剩余字节时,无法填充缓冲区。

我试图创建一个非常简单的游戏。这是它的工作原理:

  1. 一些数据被发送到套接字(8 字节)
  2. 使用 read 和 1 字节大小的缓冲区读取 1 个字节。一切都很好。
  3. 使用 read_exact 和 1 字节大小的缓冲区读取 1 个字节。一切都很好。
  4. 1 个字节应该被读取,在底层read 对象(stream 对象)上使用read_exact。无法填充缓冲区。如果我解包或具有初始值的缓冲区,我会收到错误消息。
#[cfg(test)]
mod tests {
use std::net::{TcpListener, TcpStream};
use std::io::{BufReader, Read, Write};

#[test]
fn test_read_twice() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let local_addr = listener.local_addr().unwrap();
let mut stream = TcpStream::connect(local_addr).unwrap();
match listener.accept() {
Ok((mut socket, _)) => {
let _ = socket.write_all(&[0, 1, 2, 4, 5, 7]);
}
Err(e) => println!("couldn't get client: {:?}", e),
}
{
let mut reader = BufReader::new(&mut stream);
let mut buff = vec![0u8; 1];
let _ = reader.read(&mut buff[..]).unwrap();
assert_eq!(buff, vec![0]);
let mut buff = vec![0u8; 1];
let _ = reader.read_exact(&mut buff[..]).unwrap();
assert_eq!(buff, vec![1]);
}
let mut buff = vec![88u8; 1];
let _ = stream.read_exact(&mut buff[..]);
assert_eq!(buff, vec![2]);
}
}

gist

最佳答案

一个BufReader的点是“提前”读取 - 您只进行了小读取,但是 BufReader 从底层读取器读取了一个大块,将其存储在缓冲区中,并为 read 请求提供服务从那个。此缓冲区由 BufReader 拥有 - 当您在底层调用 read(或 read_exact)时,您不能期望从该缓冲区读取读者。

由于 BufReader 接口(interface)不公开内部缓冲区,因此稍后再次使用底层读取器通常没有意义(您无法可靠地进入缓冲区为空的状态).因此,不是传递对 BufReader::new 的引用,而是简单地按值传递它。这样你就可以永远把它留在那里,并在必要时移动 BufReader/TcpStream

您仍然可以通过 get_ref 访问底层阅读器和 get_mut如果您需要调用其他(不是 Read 相关的)函数(或者甚至用 into_inner 取回它,但您将丢失缓冲数据)。

关于sockets - 在 BufReader 中包装后无法从底层读取器读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48122437/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com