diff options
author | Carl Lerche <me@carllerche.com> | 2019-10-22 10:13:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-22 10:13:49 -0700 |
commit | cfc15617a5247ea780c32c85b7134b88b6de5845 (patch) | |
tree | ef0a46c61c51505a60f386c9760acac9d1f9b7b1 /examples/udp-client.rs | |
parent | b8cee1a60ad99ef28ec494ae4230e2ef4399fcf9 (diff) |
codec: move into tokio-util (#1675)
Related to #1318, Tokio APIs that are "less stable" are moved into a new
`tokio-util` crate. This crate will mirror `tokio` and provide
additional APIs that may require a greater rate of breaking changes.
As examples require `tokio-util`, they are moved into a separate
crate (`examples`). This has the added advantage of being able to avoid
example only dependencies in the `tokio` crate.
Diffstat (limited to 'examples/udp-client.rs')
-rw-r--r-- | examples/udp-client.rs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/examples/udp-client.rs b/examples/udp-client.rs new file mode 100644 index 00000000..5437daf6 --- /dev/null +++ b/examples/udp-client.rs @@ -0,0 +1,72 @@ +//! 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. + +#![warn(rust_2018_idioms)] + +use std::env; +use std::error::Error; +use std::io::{stdin, Read}; +use std::net::SocketAddr; +use tokio::net::UdpSocket; + +fn get_stdin_data() -> Result<Vec<u8>, Box<dyn std::error::Error>> { + let mut buf = Vec::new(); + stdin().read_to_end(&mut buf)?; + Ok(buf) +} + +#[tokio::main] +async fn main() -> Result<(), Box<dyn Error>> { + let remote_addr: SocketAddr = env::args() + .nth(1) + .unwrap_or("127.0.0.1:8080".into()) + .parse()?; + + // 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()?; + + let mut socket = UdpSocket::bind(local_addr).await?; + const MAX_DATAGRAM_SIZE: usize = 65_507; + socket.connect(&remote_addr).await?; + let data = get_stdin_data()?; + socket.send(&data).await?; + let mut data = vec![0u8; MAX_DATAGRAM_SIZE]; + let len = socket.recv(&mut data).await?; + println!( + "Received {} bytes:\n{}", + len, + String::from_utf8_lossy(&data[..len]) + ); + + Ok(()) +} |