summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorDenis <gilaldpellaeon@gmail.com>2018-03-22 18:00:28 +0100
committerCarl Lerche <me@carllerche.com>2018-03-22 10:00:27 -0700
commit16d3540ce9c361144fc0b67f1da95b5294e06cd7 (patch)
tree61b565e89dadf77c70e4ce0752260057f4acd53d /examples
parente5ebd02885da0b3927d26a4a23bd0e5297d3d262 (diff)
Add UDP client example (send/recv_dgram) (#239)
Diffstat (limited to 'examples')
-rw-r--r--examples/README.md2
-rw-r--r--examples/udp-client.rs74
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),
+ }
+}