How do I serve a non-blocking UDP socket?

So I tried to create a non-blocking UDP server like this:

fn main() {
  let socket = UdpSocket::bind("127.0.0.1:5024").unwrap();
  socket.set_nonblocking(true).unwrap();

  loop {
    let mut buf = [0; 1024];
    match socket.recv_from(&mut buf) {
      Ok((len, _)) => println!("Received {} bytes.", len),
      Err(e) => eprintln!("{}", e)
    };

    sleep(Duration::new(0, 1000000000u32 / 60));
  }
}

But I got this error instead:

A non-blocking socket operation could not be completed immediately. (os error 10035)

According to the documentation, I have to handle the io::ErrorKind::WouldBlock, which I have no clue how to handle such case...

If possible, I need solutions for both windows and unix

You say you don't know how you'd handle the WouldBlock error, but you already have a sleep in the loop. Just guard the error handling arm in the match block by checking if it's a WouldBlock. Then the rest of the loop will run, sleeping and then trying again.

use std::{io::ErrorKind, net::UdpSocket, thread::sleep, time::Duration};

fn main() {
    let socket = UdpSocket::bind("127.0.0.1:5024").unwrap();
    socket.set_nonblocking(true).unwrap();

    loop {
        let mut buf = [0; 1024];
        match socket.recv_from(&mut buf) {
            Ok((len, _)) => println!("Received {} bytes.", len),
            Err(e) => {
                if !matches!(e.kind(), ErrorKind::WouldBlock) {
                    eprintln!("{}", e)
                }
            }
        };

        sleep(Duration::new(0, 1000000000u32 / 60));
    }
}

Of course there's no real reason to use a non-blocking socket if you're going to immediately sleep in the WouldBlock case, but I assume that's just placeholder code.

1 Like

When you have exhausted all work and get WouldBlock errors you wait for a notification that one or more sockets have data to read, aka readiness polling. This can be achieved with select/poll/epoll/kqueue syscalls on unix systems. Windows has some equivalent API too. The mio crate provides a portable abstraction.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.