我正在使用mio::udp::UdpSocket接收对来自客户端的请求的响应。看起来我在触发的事件上得到了部分UDP数据包。我不确定这是否是mio库中的bug。
我尝试过PollOpt:: level(),all(),empty(),edge()等。我想我通常想要基于poll()文档的level(),但它们都不起作用。通过添加20毫秒的休眠,我得到了完整的数据包。
作为参考,当使用阻塞std::net::UdpSocket时,我看不到任何问题。老实说,如果std::net::SocketOpts是稳定的,我会直接使用它。使用mio的目的是为了在套接字上获得超时,看起来net2将取代std::net,但即使是net2在recv上也没有超时。
以下是eventloop的代码:
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),
}
}发布于 2015-09-17 12:27:53
接下来,上面逻辑中的错误是run_once()只运行了一个节拍,而不是一个“事件”,这是一个糟糕的假设(尽管公平地说,接口目前没有很好的文档记录)。
在任何情况下,这都不是部分数据包问题,而是数据包在run_once()逻辑运行之前没有被传递的问题,在套接字上看不到任何东西并立即返回。
在收到包并使用run()而不是run_once()之后,我更改了我的处理程序以执行event_loop.shutdown()。
https://stackoverflow.com/questions/32580220
复制相似问题