Open1

Rust nixクレート

たけぴょんたけぴょん

Rustのnixクレートのepollが0.27から一新されたようでした。検索して出てくるのは大体が0.27以前の例なのでepoll初心者としてはどうやればいいかチンプンカンプン。
試行錯誤の末なんとか動いたので備忘録を残します。

nix::sys::epollでUDPサーバーを建てる例

UDPサーバーを2つ立て、epollで同時に受信を待つ例です。

use nix::sys::epoll::{Epoll, EpollEvent, EpollFlags, EpollTimeout, EpollCreateFlags};
use std::net::UdpSocket;
use std::os::unix::io::{AsFd, BorrowedFd};
use std::os::unix::io::{AsRawFd, RawFd};
use std::io::{BufRead, BufReader, BufWriter, Write};

const NEVENTS: usize = 16;
const MILLIS: u8 = 100;

fn main() {
    let sock1= UdpSocket::bind("127.0.0.1:11111").unwrap();
    let sock2= UdpSocket::bind("127.0.0.1:22222").unwrap();
    let epoll = Epoll::new(EpollCreateFlags::empty()).unwrap();
    let ev = EpollEvent::new(EpollFlags::EPOLLIN, sock1.as_raw_fd() as u64);
    epoll.add(sock1.as_fd(), ev).unwrap();
    let ev = EpollEvent::new(EpollFlags::EPOLLIN, sock2.as_raw_fd() as u64);
    epoll.add(sock2.as_fd(), ev).unwrap();
    let mut events = vec![EpollEvent::empty(); NEVENTS];
    loop {
        if let Ok(nfds) = epoll.wait(&mut events, MILLIS) {
            for n in 0..nfds {
                let mut buf = vec![0u8; 1024];
                if events[n].data() == sock1.as_raw_fd() as u64 {
                    println!("Socket1:");
                    match sock1.recv(&mut buf) {
                        Ok(n) => println!("    received={:?}", &buf[..n]),
                        Err(e) => println!("    {e}"),
                    }
                }
                if events[n].data() == sock2.as_raw_fd() as u64 {
                    println!("Socket2:");
                    match sock2.recv(&mut buf) {
                        Ok(n) => println!("    received={:?}", &buf[..n]),
                        Err(e) => println!("    {e}"),
                    }
                }
            }
        }
    }
}

ぶっちゃけよくわからず書いているところもある、、、

上記のコードを

cargo run

で動かし、別のターミナルから

nc -u 127.0.0.1 11111
Hello
hello
nc -u 127.0.0.1 22222
Yeah miteru?

とかやるとどちらも受信できます。