gpt4 book ai didi

rust - 如何在数据结构中存储带有 BufReader 和 BufWriter 的 TcpStream

转载 作者:行者123 更新时间:2023-11-29 08:19:44 28 4
gpt4 key购买 nike

我想要一个 TcpStream由一个 BufReader 共享和一个 BufWriter ,我在以下地方找到了解决方案:
If BufReader takes ownership of a stream, how can I read and write lines on it?

现在我想要它在它自己的数据结构中,但我只得到了部分答案:
Why can't I store a value and a reference to that value in the same struct?

所需的实现违反了所有权规则。

use std::io::{BufReader, BufWriter};
use std::net::TcpStream;

pub struct BufTcpStream<'a> {
_socket: TcpStream,
input: BufReader<&'a TcpStream>;
output: BufWriter<&'a TcpStream>;
}

impl<'a> BufTcpStream<'a> {
pub fn new(socket: TcpStream) -> Self {
Self{
input : BufReader::new(&socket),
output: BufWriter::new(&socket),
_socket: socket,// <-- MOVE OF BORROWED VALUE HERE
}
}
}

为了解决这个问题,我必须确保 TcpStream引用将在整个结构生命周期内保持有效,我使用了 Pin<Box<TcpStream>>以确保它。

但编译器仍然提示借用值的移动socket .为了消除这个障碍,我使用了 std::meme::transmute() .

现在,我想知道的是:

这个实现安全吗?

use std::io::{BufReader, BufWriter};
use std::net::TcpStream;
use std::pin::Pin;

pub struct BufTcpStream<'a> {
_socket: Pin<Box<TcpStream>>,
input : BufReader<&'a TcpStream>,
output: BufWriter<&'a TcpStream>,
}

impl<'a> BufTcpStream<'a> {
pub fn new(socket: TcpStream) -> Self {
let pin = Box::pin(socket);
unsafe {
Self{
input : BufReader::new(std::mem::transmute(&*pin)),
output: BufWriter::new(std::mem::transmute(&*pin)),
_socket: pin,
}
}
}
pub fn reach(&mut self) -> (
&mut BufReader<&'a TcpStream>,
&mut BufWriter<&'a TcpStream>
) {
(&mut self.input, &mut self.output)
}
}

最佳答案

使用TcpStream::try_clone获得第二个流:

The returned TcpStream is a reference to the same stream that this object references. Both handles will read and write the same stream of data, and options set on one stream will be propagated to the other stream.

然后您可以将一个包装在 reader 中,将一个包装在 writer 中:

use std::{
io::{self, BufReader, BufWriter},
net::TcpStream,
};

struct BufTcpStream {
input: BufReader<TcpStream>,
output: BufWriter<TcpStream>,
}

impl BufTcpStream {
fn new(stream: TcpStream) -> io::Result<Self> {
let input = BufReader::new(stream.try_clone()?);
let output = BufWriter::new(stream);

Ok(Self { input, output })
}
}

另见:

关于rust - 如何在数据结构中存储带有 BufReader 和 BufWriter 的 TcpStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58467659/

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