When does a broken pipe occur in a TCP stream?
Asked Answered
S

1

14

I am trying to write an echo server in Rust.

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

fn main() {
    let listener = TcpListener::bind("0.0.0.0:8000").unwrap();
    for stream in listener.incoming() {
        let stream = stream.unwrap();
        println!("A connection established");
        handle_connection(stream);
    }

}

fn handle_connection(mut stream: TcpStream) {
    let mut buffer = [0; 512];

    stream.read(&mut buffer).unwrap();

    println!("Request: {}", String::from_utf8_lossy(&buffer[..]));
    stream.write(&buffer[..]).unwrap();
    stream.flush().unwrap();
}

The first request with nc localhost 8000 is working as expected but subsequent request aren't. What am I doing wrong? Is the problem in how the server is reading requests from clients? Though there is no error server side.

I am sending data by typing them on the terminal:

$ nc localhost 8000
hi
hi
hello
# no response
# on pressing enter
Ncat: Broken pipe.
Syllabize answered 14/8, 2017 at 5:52 Comment(2)
"but subsequent request aren't. " Please be specific. How are you sending data via nc? What exact error are you getting? You code seems to work for me.Midtown
@Midtown I am sending data by typing them on the terminal. Updated the questionSyllabize
P
21

A 'Broken pipe' message happens when you write to a stream where the other end has been closed. In your example, your handle_connection routine reads a single buffer from the client, copies that back to the client, and then returns, which will close the stream. When you run netcat from the terminal like that, the terminal defaults to line buffering, so each line you type will be sent to the server as a single write.

The first line is sent, read by the server, echoed back, and then the server closes the connection. Netcat gets a second line, writes that to the socket, and gets a 'Broken pipe' because the server has closed the connection.

If you want your server to read multiple messages, you need to have your handle_connection routine loop, reading from the stream until it gets an EOF.

Principality answered 14/8, 2017 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.