Skip to content

Instantly share code, notes, and snippets.

@elyzion
Last active August 29, 2015 13:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save elyzion/8816127 to your computer and use it in GitHub Desktop.
Save elyzion/8816127 to your computer and use it in GitHub Desktop.
A very simple echo server.
//! A simplistic echo server that allows client to exit using the quit command.
#![crate_id = "echo:0.1pre"]
#![feature(phase)]
#[phase(plugin, link)] extern crate log;
use std::io::{Listener, Acceptor, BufferedStream};
use std::io::net::tcp::TcpListener;
fn main() {
let addr = Config {
ip: "127.0.0.1",
port: 9123
};
let mut acceptor = match TcpListener::bind(addr.ip, addr.port).listen() {
Err(err) => {
error!("Bind or listen failed: {}", err);
//Exit the process by returning from the main method.
return
},
Ok(acceptor) => acceptor,
};
println!("Listening for connections.");
for connection in acceptor.incoming() {
match connection {
Ok(stream) => {
spawn(proc() {
//Reassign stream to a mutable variables.
//This is required for the peer_name call.
//This is actually not required, once issue https://github.com/mozilla/rust/issues/12260
//is fixed, we can use Ok(mut stream) instead of this.
let mut stream = stream;
let peer_name: String = stream.peer_name().unwrap().to_str();
println!("Client connected: {}", peer_name);
//BufferedStream allows for tuning buffer sizes,
//but it is not required for this case.
let mut stream = BufferedStream::new(stream);
loop {
match stream.read_line() {
Ok(line) => {
//If syntax would be much simpler.
match line.as_slice().trim() {
//Disconnect the client on the quit command.
"quit" => break,
//Other commands can be added in the same way as the quit command.
//Anything that is not a command we echo here.
_ => {
stream.write(line.as_bytes());
stream.flush()
},
};
},
Err(_) => continue, //This is a bad thing as some errors are permanent.
};
};
//FIXME: do we need to perform a drop here to close to connection properly?
println!("Client disconnected: {}", peer_name)
})
},
Err(err) => {
debug!("An error occured processing a socket connection: {}", err);
continue
}, //This is a bad thing as some errors are permanent.
};
}
}
//Will expand this with more configuration options.
pub struct Config {
ip: &'static str,
port: u16
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment