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),
}
}