Skip to content

Instantly share code, notes, and snippets.

@emaxerrno
Forked from elyzion/echo.rs
Created February 14, 2014 03:41
Show Gist options
  • Select an option

  • Save emaxerrno/8995387 to your computer and use it in GitHub Desktop.

Select an option

Save emaxerrno/8995387 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 = "main:0.1pre"];
#[crate_type = "bin"];
use std::io::{Listener, Acceptor, BufferedStream};
use std::io::net::tcp::TcpListener;
use std::io::net::ip::{SocketAddr, Ipv4Addr};
//use std::io::io_error; //Not using this at the moment.
//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(stream) => {
spawn(proc() {
//FIXME: Is there a better way of getting peer_name and creating BufferedStream?
//This is OK for an echo server, more complex cases should wrap this in something like Cell?
let mut m_stream = stream;
let peer_name: ~str = m_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 buffered_stream = BufferedStream::new(m_stream);
loop {
match buffered_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.
_ => {
buffered_stream.write(line.into_bytes());
buffered_stream.flush()
},
}
},
Err(err) => continue,
};
}
//FIXME: do we need to perform a drop here to close to connectio 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