You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
3.0 KiB
78 lines
3.0 KiB
// You can run this example from the root of the mio repo:
|
|
// cargo run --example udp_server --features="os-poll udp"
|
|
use log::warn;
|
|
use mio::net::UdpSocket;
|
|
use mio::{Events, Interest, Poll, Token};
|
|
use std::io;
|
|
|
|
// A token to allow us to identify which event is for the `UdpSocket`.
|
|
const UDP_SOCKET: Token = Token(0);
|
|
|
|
fn main() -> io::Result<()> {
|
|
env_logger::init();
|
|
|
|
// Create a poll instance.
|
|
let mut poll = Poll::new()?;
|
|
// Create storage for events. Since we will only register a single socket, a
|
|
// capacity of 1 will do.
|
|
let mut events = Events::with_capacity(1);
|
|
|
|
// Setup the UDP socket.
|
|
let addr = "127.0.0.1:9000".parse().unwrap();
|
|
let mut socket = UdpSocket::bind(addr)?;
|
|
|
|
// Register our socket with the token defined above and an interest in being
|
|
// `READABLE`.
|
|
poll.registry()
|
|
.register(&mut socket, UDP_SOCKET, Interest::READABLE)?;
|
|
|
|
println!("You can connect to the server using `nc`:");
|
|
println!(" $ nc -u 127.0.0.1 9000");
|
|
println!("Anything you type will be echoed back to you.");
|
|
|
|
// Initialize a buffer for the UDP packet. We use the maximum size of a UDP
|
|
// packet, which is the maximum value of 16 a bit integer.
|
|
let mut buf = [0; 1 << 16];
|
|
|
|
// Our event loop.
|
|
loop {
|
|
// Poll to check if we have events waiting for us.
|
|
poll.poll(&mut events, None)?;
|
|
|
|
// Process each event.
|
|
for event in events.iter() {
|
|
// Validate the token we registered our socket with,
|
|
// in this example it will only ever be one but we
|
|
// make sure it's valid none the less.
|
|
match event.token() {
|
|
UDP_SOCKET => loop {
|
|
// In this loop we receive all packets queued for the socket.
|
|
match socket.recv_from(&mut buf) {
|
|
Ok((packet_size, source_address)) => {
|
|
// Echo the data.
|
|
socket.send_to(&buf[..packet_size], source_address)?;
|
|
}
|
|
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
|
|
// If we get a `WouldBlock` error we know our socket
|
|
// has no more packets queued, so we can return to
|
|
// polling and wait for some more.
|
|
break;
|
|
}
|
|
Err(e) => {
|
|
// If it was any other kind of error, something went
|
|
// wrong and we terminate with an error.
|
|
return Err(e);
|
|
}
|
|
}
|
|
},
|
|
_ => {
|
|
// This should never happen as we only registered our
|
|
// `UdpSocket` using the `UDP_SOCKET` token, but if it ever
|
|
// does we'll log it.
|
|
warn!("Got event for unexpected token: {:?}", event);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|