1

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

1 に答える 1