Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When does a broken pipe occur in a TCP stream?

Tags:

tcp

rust

netcat

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.
like image 286
codeNoob Avatar asked Aug 14 '17 05:08

codeNoob


Video Answer


1 Answers

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.

like image 149
Chris Dodd Avatar answered Sep 30 '22 19:09

Chris Dodd