diff options
author | Denis <gilaldpellaeon@gmail.com> | 2018-03-22 18:00:28 +0100 |
---|---|---|
committer | Carl Lerche <me@carllerche.com> | 2018-03-22 10:00:27 -0700 |
commit | 16d3540ce9c361144fc0b67f1da95b5294e06cd7 (patch) | |
tree | 61b565e89dadf77c70e4ce0752260057f4acd53d /examples | |
parent | e5ebd02885da0b3927d26a4a23bd0e5297d3d262 (diff) |
Add UDP client example (send/recv_dgram) (#239)
Diffstat (limited to 'examples')
-rw-r--r-- | examples/README.md | 2 | ||||
-rw-r--r-- | examples/udp-client.rs | 74 |
2 files changed, 76 insertions, 0 deletions
diff --git a/examples/README.md b/examples/README.md index 735c186f..cd3c0ba3 100644 --- a/examples/README.md +++ b/examples/README.md @@ -47,6 +47,8 @@ A high level description of each example is: * [`tinydb`](tinydb.rs) - an in-memory database which shows sharing state between all connected clients, notably the key/value store of this database. +* [`udp-client`](udp-client.rs) - a simple `send_dgram`/`recv_dgram` example. + If you've got an example you'd like to see here, please feel free to open an issue. Otherwise if you've got an example you'd like to add, please feel free to make a PR! diff --git a/examples/udp-client.rs b/examples/udp-client.rs new file mode 100644 index 00000000..3af7c3be --- /dev/null +++ b/examples/udp-client.rs @@ -0,0 +1,74 @@ +//! A UDP client that just sends everything it gets via `stdio` in a single datagram, and then +//! waits for a reply. +//! +//! For the reasons of simplicity data from `stdio` is read until `EOF` in a blocking manner. +//! +//! You can test this out by running an echo server: +//! +//! ``` +//! $ cargo run --example echo-udp -- 127.0.0.1:8080 +//! ``` +//! +//! and running the client in another terminal: +//! +//! ``` +//! $ cargo run --example udp-client +//! ``` +//! +//! You can optionally provide any custom endpoint address for the client: +//! +//! ``` +//! $ cargo run --example udp-client -- 127.0.0.1:8080 +//! ``` +//! +//! Don't forget to pass `EOF` to the standard input of the client! +//! +//! Please mind that since the UDP protocol doesn't have any capabilities to detect a broken +//! connection the server needs to be run first, otherwise the client will block forever. + +extern crate futures; +extern crate tokio; + +use std::env; +use std::io::stdin; +use std::net::SocketAddr; +use tokio::net::UdpSocket; +use tokio::prelude::*; + +fn get_stdin_data() -> Vec<u8> { + let mut buf = Vec::new(); + stdin().read_to_end(&mut buf).unwrap(); + buf +} + +fn main() { + let remote_addr: SocketAddr = env::args() + .nth(1) + .unwrap_or("127.0.0.1:8080".into()) + .parse() + .unwrap(); + // We use port 0 to let the operating system allocate an available port for us. + let local_addr: SocketAddr = if remote_addr.is_ipv4() { + "0.0.0.0:0" + } else { + "[::]:0" + }.parse() + .unwrap(); + let socket = UdpSocket::bind(&local_addr).unwrap(); + const MAX_DATAGRAM_SIZE: usize = 65_507; + let processing = socket + .send_dgram(get_stdin_data(), &remote_addr) + .and_then(|(socket, _)| socket.recv_dgram(vec![0u8; MAX_DATAGRAM_SIZE])) + .map(|(_, data, len, _)| { + println!( + "Received {} bytes:\n{}", + len, + String::from_utf8_lossy(&data[..len]) + ) + }) + .wait(); + match processing { + Ok(_) => {} + Err(e) => eprintln!("Encountered an error: {}", e), + } +} |