Skip to content

Instantly share code, notes, and snippets.

@seriyps
Last active November 17, 2022 10:08
Show Gist options
  • Save seriyps/fd6d29442e16c44ba400 to your computer and use it in GitHub Desktop.
Save seriyps/fd6d29442e16c44ba400 to your computer and use it in GitHub Desktop.
Simple concurrent TCP echo server (rust 0.11)
#![feature(phase)]
#[phase(plugin, link)] extern crate log;
extern crate green;
extern crate rustuv;
use std::io;
use std::os;
use std::io::{Listener,Acceptor,TcpStream};
#[start]
fn start(argc: int, argv: *const *const u8) -> int {
green::start(argc, argv, rustuv::event_loop, main)
}
fn main() {
let args = os::args();
if args.len() < 3 {
println!("Usage: {} <ip> <port>", args[0]);
os::set_exit_status(1);
return
}
let host = args[1].as_slice();
let port = from_str::<u16>(args[2].as_slice()).unwrap();
let sock = io::TcpListener::bind(host, port).unwrap();
let mut acceptor = sock.listen();
debug!("Listening...");
for stream in acceptor.incoming() {
match stream {
Err(e) => warn!("Accept err {}", e),
Ok(stream) => {
spawn(proc() {
println!("{}", handle_client(stream));
})
}
}
}
}
type Buf = [u8, ..10240];
fn handle_client(mut stream: io::TcpStream) -> io::IoResult<()> {
info!("New client {}", stream.peer_name());
let mut buf: Buf = [0u8, ..10240];
let (child_tx, parent_rx) = channel::<Buf>();
let (parent_tx, child_rx) = channel::<Buf>();
spawn(proc() {
// if this `deschedule` will be commented, only one CPU core will be used (rust 0.11)
std::task::deschedule();
for mut buf in child_rx.iter() {
for _ in range::<u8>(0, 20) {
buf.reverse();
}
child_tx.send(buf);
};
});
loop {
let got = try!(stream.read(buf));
if got == 0 {
// Is it possible? Or IoError will be raised anyway?
break
}
// outsource CPU-heavy work to separate task, because current green+libuv
// implementation bind all IO tasks to one scheduler (rust 0.11)
// see https://botbot.me/mozilla/rust/2014-08-01/?msg=18995736&page=11
parent_tx.send(buf);
let to_send: Buf = parent_rx.recv();
try!(stream.write(to_send.slice(0, got)));
}
Ok(())
}
@seriyps
Copy link
Author

seriyps commented Aug 31, 2015

@ferouswheel yep. This worked with Rust 0.11. For now it's not possible to write smth equal using just Rust standard library.

@dariusc93
Copy link

You can use several libraries to replace green or rustuv. mioco is a good alt to those two. If you want to get completely low level, you could make bindings around libev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment