Rust Echo Server Example

There are many examples of TCP servers in Rust, and even echo servers, but I found many of them to be too complex. I think echo servers to be the best example for getting started writing servers in a new language, so I figured I’d write my own.

UPDATE Dec 19, 2016: For a cleaner example, check out Peter Kolloch’s comment below; I think it’s a lot nicer than my example, and I haven’t really touched Rust this past year, so I’m not sure what best practices are these days.

Note: A lot of this stuff is marked ‘unstable’, so you’ll get compiler warnings. If they turn into errors, please let me know so I can update the example.

The code itself should be fairly self-explanatory:

use std::net::{TcpListener, TcpStream};
use std::thread;

// traits
use std::io::Read;
use std::io::Write;

fn handle_client(mut stream: TcpStream) {
    let mut buf;
    loop {
        // clear out the buffer so we don't send garbage
        buf = [0; 512];
        let _ = match buf) {
            Err(e) => panic!("Got an error: {}", e),
            Ok(m) => {
                if m == 0 {
                    // we've got an EOF

        match stream.write(&buf) {
            Err(_) => break,
            Ok(_) => continue,

fn main() {
    let listener = TcpListener::bind("").unwrap();
    for stream in listener.incoming() {
        match stream {
            Err(e) => { println!("failed: {}", e) }
            Ok(stream) => {
                thread::spawn(move || {

The semantics for move || are described in RFC 231.

Soon I’ll update this article with a similar example using UDP.

UPDATE Feb 13, 2015: Updated the example to account for the new io and net modules.

UPDATE Dec 30, 2015: Thanks to Hans Koch in the comments for pointing out that std::thread::Thread is no longer a thing; you now use std::thread.