我正在使用 mio::udp::UdpSocket 接收对来自客户端的请求的响应。看起来我在触发事件上收到了部分 UDP 数据包。我不确定这是否是 mio 库中的错误。
我已经尝试过 PollOpt::level()、all()、empty()、edge() 等。我想我通常想要基于 poll() 文档的 level(),但它们都不起作用。通过添加 20 毫秒的睡眠,我得到了完整的数据包。
作为参考,当使用阻塞 std::net::UdpSocket 时,我看不到任何问题。老实说,如果 std::net::SocketOpts 稳定,我会使用它。使用 mio 的目的是在套接字上获得超时,看起来 net2 将替换 std::net,但即使 net2 在 recv 上也没有超时。
这是事件循环的代码:
sleep_ms(20);
let mut event_loop: EventLoop<Response> = try!(EventLoop::new());
if event_loop.timeout_ms((), 5000).is_err() { return Err(ClientError::TimerError) };
try!(event_loop.register_opt(&self.socket, RESPONSE, EventSet::readable(), PollOpt::all()));
let mut response: Response = Response::new(&self.socket);
try!(event_loop.run_once(&mut response));
这是处理程序的代码:
fn ready(&mut self, _: &mut EventLoop<Self>, token: Token, events: EventSet) {
match token {
RESPONSE => {
if !events.is_readable() {
debug!("got woken up, but not readable: {:?}", token);
return
}
let recv_result = self.socket.recv_from(&mut self.buf);
if recv_result.is_err() {
// debug b/c we're returning the error explicitly
debug!("could not recv_from on {:?}: {:?}", self.socket, recv_result);
self.error = Some(recv_result.unwrap_err().into());
return
}
if recv_result.as_ref().unwrap().is_none() {
// debug b/c we're returning the error explicitly
debug!("no return address on recv_from: {:?}", self.socket);
self.error = Some(ClientError::NoAddress);
return
}
let addr = Some(recv_result.unwrap().unwrap());
debug!("bytes: {:?} from: {:?}", self.buf.len(), addr);
},
_ => error!("unrecognized token: {:?}", token),
}
}