Rust has a minimal UDP package in std::net::UdpSocket
.
This is good enough for basic use. It uses the functions
recv_from()
and send_to()
to read and write from a UDP socket.
The socket is bound to 0.0.0.0:2000
for UDP4 only
or [::]:2000
for dual stack UDP4 or UDP6.
The project is created by cargo new echoserver
and built and run from within the directory echoserver
The file src/main.rs
should contain
EchoServer.rs:
//use std::io::{self, Read, Write, BufRead};
use std::net::UdpSocket;
//use std::env;
//use std::str;
fn main() -> std::io::Result<()> {
//let socket = UdpSocket::bind("0.0.0.0:2000")?; // for UDP4
let socket = UdpSocket::bind("[::]:2000")?; // for UDP4/6
let mut buf = [0; 2048];
loop {
// Receives a single datagram message on the socket.
// If `buf` is too small to hold
// the message, it will be cut off.
let (amt, src) = socket.recv_from(&mut buf)?;
// Redeclare `buf` as slice of the received data
// and send data back to origin.
let buf = &mut buf[..amt];
socket.send_to(buf, &src)?;
}
}
The EchoClient is similar to the TCP case, except for the actual communication
(of course!). One pecularity of the Rust implementation of UDP is the
requirement to bind the client to an address/port. Even in C, you don't
have to do that! I've chosen to use the wildcard address ::
and
the zero port to lead to an ephemeral port as [::]:0
.
Apart from that, it uses send_to()
and recv_from()
as in the server.
The code is EchoClient.rs:
use std::io::{self, BufRead};
use std::net::UdpSocket;
use std::env;
use std::str;
fn main() -> std::io::Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Usage {} hostname", args[0]);
std::process::exit(1);
}
let hostname = &args[1];
let socket = UdpSocket::bind("[::]:0")?; // for UDP4/6
//socket.connect(hostname.to_string() + &":2000").expect("couldn't connect to address");
// from https://stackoverflow.com/questions/30186037/how-can-i-read-a-single-line-from-stdin
let stdin = io::stdin();
for line in stdin.lock().lines() {
let line = line.unwrap();
println!("Line read from stdin '{}'", line);
if &line == "BYE" {
break;
}
socket.send_to(line.as_bytes(), hostname.to_string() + &":2000")
.expect("Error on send");
let mut buf = [0; 2048];
let (amt, _src) = socket.recv_from(&mut buf)?;
let echo = str::from_utf8(&buf[..amt]).unwrap();
println!("Echo {}", echo);
}
Ok(())
}
Copyright © Jan Newmarch, jan@newmarch.name
" Network Programming using Java, Go, Python, Rust, JavaScript and Julia"
by
Jan Newmarch
is licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License
.
Based on a work at
https://jan.newmarch.name/NetworkProgramming/
.