Last active
November 17, 2022 10:08
-
-
Save seriyps/fd6d29442e16c44ba400 to your computer and use it in GitHub Desktop.
Simple concurrent TCP echo server (rust 0.11)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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(()) | |
} |
@ferouswheel yep. This worked with Rust 0.11. For now it's not possible to write smth equal using just Rust standard library.
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
Tried to get this working with rust 1.2.0, but there are the following issues:
proc()
no longer exists, and needs to be replaced by||
type Buf = [u8; 10240];
Haven't discovered an alternative with mio or something yet, but wanted to comment to save other people time.