forked from Xudong-Huang/may
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathecho_udp.rs
93 lines (78 loc) · 2.12 KB
/
echo_udp.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
extern crate docopt;
#[macro_use]
extern crate may;
#[macro_use]
extern crate serde_derive;
// use std::time::Duration;
// use std::io::ErrorKind;
use may::coroutine;
use may::net::UdpSocket;
use docopt::Docopt;
const VERSION: &str = "0.1.0";
const USAGE: &str = "
Udp echo server.
Usage:
echo_udp [-t <threads>] [-p <port>]
echo_udp (-h | --help)
echo_udp (-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: 30000].
";
#[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) => {
println!("call = {:?}\nerr = {:?}", stringify!($e), err);
continue;
}
}
};
}
/// simple test: echo hello | nc -u 127.0.0.1 30000
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_udp: {VERSION}");
}
let port = args.flag_p;
let threads = args.flag_t;
may::config().set_workers(threads);
let sock = UdpSocket::bind(("0.0.0.0", port)).unwrap();
println!(
"Starting udp echo server on {:?}\nRunning on {} threads",
sock.local_addr().unwrap(),
threads
);
let mut handlers = Vec::new();
for _ in 0..threads {
let sock = t!(sock.try_clone());
let h: coroutine::JoinHandle<()> = go!(move || {
let mut buf = vec![0u8; 1024 * 16];
loop {
let (len, addr) = t!(sock.recv_from(&mut buf));
// println!("recv_from: len={:?} addr={:?}", len, addr);
let mut rest = len;
while rest > 0 {
let i = t!(sock.send_to(&buf[(len - rest)..len], addr));
rest -= i;
}
}
});
handlers.push(h);
}
for j in handlers {
j.join().unwrap();
}
}