Open1
Rust nixクレート
![たけぴょん](https://res.cloudinary.com/zenn/image/fetch/s--V-QoT9Iu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/6a4e038c53.jpeg)
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?
とかやるとどちらも受信できます。