0

I'm trying to build a simple client crate for a program that has it's own simple TCP protocol.

Most of the communication works by sending a command and immediately reading a single line response. Some of the commands need to read multiple responses. I've been using BufReader::read_line() to read single lines but this seems to fall down when it reads too much, the second read_line() can be missing the start of the line.

My assumption is that I'm meant to be keeping the BufReader around so that it keeps its internal state.

I'm doing this by passing a reference of the TcpStream to the BufReader and BufWriter but I'm getting “borrowed value does not live long enough”. My question is; where do I “store” the TcpStream so that it does live long enough?

I've tried different iterations of trying to store the stream on the Connection struct but I can't seem to get it to work.

Here is a cut down version of the code:

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

#[derive(Debug)]
pub struct Connection<'a> {
    reader: BufReader<&'a TcpStream>,
    writer: BufWriter<&'a TcpStream>,
}

impl<'a> Connection<'a> {
    pub fn new(stream: TcpStream) -> io::Result<Self> {
        let connection = Self {
            reader: BufReader::new(&stream),
            writer: BufWriter::new(&stream),
        };

        Ok(connection)
    }
}

pub struct Search<'a> {
    connection: Connection<'a>,
}

impl<'a> Search<'a> {
    // fn new(stream: &'a TcpStream) -> Self {
    fn new() -> Self {
        let stream = TcpStream::connect("127.0.0.1:100").unwrap();
        let connection = Connection::new(stream).unwrap();

        Self { connection }
    }
}

fn main() {
    // let stream = TcpStream::connect("127.0.0.1:100").unwrap();
    // Search::new(&stream);

    Search::new();
}

If I uncomment the commented-out lines it works.

twe4ked
  • 2,832
  • 21
  • 24
  • You was close, https://play.integer32.com/?version=stable&mode=debug&edition=2018&gist=91088e29b5192d2e2475c7387ec7d88b, consider use [`bufstream`](https://docs.rs/bufstream/0.1.4/bufstream/) – Stargateur Apr 22 '19 at 05:47
  • @Stargateur thanks for taking a look. I wasn't clear enough in my original question but I'd really like the API to look like the un-commented code. So the `::new()` function is responsible for creating the `TcpStream`. I don't think the other question is a duplicate because I'm still not clear on where to “store” the stream. – twe4ked Apr 22 '19 at 05:58
  • 1
    You can't see: [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – Stargateur Apr 22 '19 at 06:06
  • Aha! https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct explains it perfectly. Thanks very much. – twe4ked Apr 22 '19 at 06:23
  • If anyone has any other ideas on how to structure this code, please let me know. – twe4ked Apr 22 '19 at 22:49
  • 1
    As I said, use bufstream, https://play.integer32.com/?version=stable&mode=debug&edition=2018&gist=3e4faf993fc0c49cf5d9da45d5938ec6 – Stargateur Apr 23 '19 at 00:21

0 Answers0