TcpStream::connect in a loop

I'm very new to Rust and trying to write a simple chat app without using any external crates just as a start. I already have a very simple backend server (based on the rust book example) which binds to localhost port 8080 and respond to GET or POST request. Now I'm trying to do the client side where I use TcpStream::connect to connect to the server, and repeatedly send POST requests every 5 seconds, just as a test. What I'm witnessing is that if TcpStream::connect is outside the loop then after the first message the connection is lost Broken pipe (os error 32) whereas within the loop it works but to me it does not make sense to do connect request every iteration. I am probably missing something very obvious, and appreciate all the help.

Client code snippet

use std::io::{self, Write, BufRead, Read};
use std::net::{TcpStream, Shutdown};
use std::thread;
use std::time::Duration;

fn main() -> io::Result<()> {

    let mut stream = TcpStream::connect( "127.0.0.1:8080")?;

    loop {
        let body = String::from("testing");
        let request = format!(
            "POST /path/to/endpoint HTTP/1.1\r\n\
             Host: example.com\r\n\
             Content-Type: application/json\r\n\
             Content-Length: {}\r\n\
             \r\n\
             {}", 
             body.len(),
             body
        );

       
        stream.write_all(request.as_bytes())?;
        println!("Sent: {}", request);

        thread::sleep(Duration::from_secs(5));
    }
}

It sounds like the other side is dropping the connection after one message.

1 Like

I see, this is my backend server, pretty much what's in the Rust book.
but I can't see where this connection drop is forced after receiving one message.

use std::{
    fs,
    io::{prelude::*, BufReader},
    net::{TcpListener, TcpStream},
};

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();

        handle_connection(stream);
    }
}


fn handle_connection(mut stream: TcpStream) {
    let buf_reader = BufReader::new(&mut stream);
    let request_line = buf_reader.lines().next().unwrap().unwrap();

    let contents = String::from("message received by backend Server");
    stream.write_all(contents .as_bytes()).unwrap();
}

The connection is dropped when stream is dropped, which happens at the end of handle_connection. You most likely want to loop inside handle_connection so that it can communicate multiple times on the same connection, which is what your client is trying to do.

1 Like

OMG! Thank you so much ... I was about to go crazy .. this totally makes sense. Appreciate the help!

1 Like