Skip to content

Instantly share code, notes, and snippets.

@elyzion
Created February 14, 2014 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elyzion/8997277 to your computer and use it in GitHub Desktop.
Save elyzion/8997277 to your computer and use it in GitHub Desktop.
//! A simplistic echo server that allows client to exit using the quit command.
//! Based on various examples and sources from the internet.
#[crate_id = "echo:0.1pre"];
use std::io::{Listener, Acceptor, BufferedStream};
use std::io::net::tcp::TcpListener;
use std::io::net::ip::{SocketAddr, Ipv4Addr};
//FIXME: In general, need more error handling.
fn main() {
let addr = Config { bind_address: SocketAddr {
ip: Ipv4Addr(127, 0, 0, 1),
port: 9123 } };
let mut acceptor = match TcpListener::bind(addr.bind_address).listen() {
Err(err) => {
error!("Bind or listen failed: {}", err);
return
},
Ok(acceptor) => acceptor,
};
println!("Listening for connections.");
for connection in acceptor.incoming() {
match connection {
Ok(mut stream) => {
spawn(proc() {.
//let mut stream = stream;
//Error occurs in the below line.
let peer_name: ~str = stream.peer_name().unwrap().to_str();
//The println! macro uses the fmt! macro internally.
//https://github.com/mozilla/rust/commit/948334f33398f0ba073107585b8dfaa0dc9feaa9
//println!("Client connected: {}", peer_name);
//Can also use the println function. Which one of the two is prefered?
//stdio::println("Accepted client " + 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.
//Which of the two is the most idiomatic though?
match line {
//Disconnect the client on the quit command.
_ if line.trim() == "quit" => break,
//Otherwise we echo everything.
_ => {
stream.write(line.into_bytes());
stream.flush()
},
};
},
Err(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 {
bind_address: SocketAddr,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment