-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathecho.rs
98 lines (83 loc) · 2.35 KB
/
echo.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
extern crate docopt;
#[macro_use]
extern crate mco;
#[macro_use]
extern crate serde_derive;
// use std::time::Duration;
use std::io::{Read, Write};
use docopt::Docopt;
use mco::net::{TcpListener, TcpStream};
const VERSION: &str = "0.1.0";
const USAGE: &str = "
Tcp echo server.
Usage:
echo [-t <threads>] [-p <port>]
echo (-h | --help)
echo (-v | --version)
Options:
-h --help Show this screen.
-v --version Show version.
-t <threads> number of threads to use [default: 1].
-p <address> port of the server [default: 3000].
";
#[derive(Debug, Deserialize)]
struct Args {
flag_p: u16,
flag_t: usize,
flag_v: bool,
}
macro_rules! t {
($e:expr) => {
match $e {
Ok(val) => val,
Err(err) => return println!("err = {:?}", err),
}
};
}
#[inline]
fn handle_client(mut stream: TcpStream) {
// t!(stream.set_read_timeout(Some(Duration::from_secs(10))));
// t!(stream.set_write_timeout(Some(Duration::from_secs(10))));
let mut read = vec![0; 1024 * 16]; // alloc in heap!
loop {
let n = t!(stream.read(&mut read));
if n > 0 {
t!(stream.write_all(&read[0..n]));
} else {
break;
}
}
}
/// simple test: echo hello | nc 127.0.0.1 3000
fn main() {
let args: Args = Docopt::new(USAGE)
.and_then(|d| d.deserialize())
.unwrap_or_else(|e| e.exit());
if args.flag_v {
return println!("echo: {}", VERSION);
}
let port = args.flag_p;
let threads = args.flag_t;
mco::config().set_workers(threads);
mco::coroutine::scope(|s| {
for i in 0..threads {
co!(s, move || {
// let listener = TcpListener::bind("127.0.0.1:3000").unwrap();
let listener = TcpListener::bind(("0.0.0.0", port)).unwrap();
println!(
"Starting tcp echo server on {:?}",
listener.local_addr().unwrap(),
);
println!("running on thread id {}", i);
for stream in listener.incoming() {
match stream {
Ok(s) => {
co!(move || handle_client(s));
}
Err(e) => println!("err = {:?}", e),
}
}
});
}
});
}