MIO EventLoop не работает для TcpStream

Я начинающий Rust, борюсь с проблемой асинхронного ввода-вывода. Я решил использовать Mio.

Я прочитал некоторые исходные коды + учебные пособия, но есть еще фундаментальная часть, которую я не понимаю. Я настраиваю сервер с netcat -k -l 127.0.0.1 9999, Затем я запускаю простой тест с cargo (код ниже). Я ожидал увидеть панику с "готово" или "тик". Но этого никогда не происходит, и тест работает вечно.

extern crate mio;
use mio::*;
#[allow(unused_imports)]
use mio::tcp::TcpStream;

#[allow(dead_code)]
struct MyHandler;

impl Handler for MyHandler {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, _event_loop: &mut EventLoop<Self>, _token: Token, _event_set: EventSet) {
        panic!("ready");
    }

    fn tick(&mut self, _event_loop: &mut EventLoop<Self>) {
        panic!("tick");
    }
}

#[test]
fn mio_test1() {
    let addr = "127.0.0.1:9999".parse().unwrap();
    let mut event_loop = EventLoop::<MyHandler>::new().unwrap();
    event_loop.register(&TcpStream::connect(&addr).unwrap(), Token(0), EventSet::readable(), PollOpt::level()).unwrap();
    event_loop.run(&mut MyHandler).unwrap();
}

1 ответ

Решение

Ваша проблема возникает из-за того, что открытый вами сокет закрывается до того, как ваш цикл обработки событий сможет запустить.

Ваш текущий код примерно эквивалентен этому:

let addr = "127.0.0.1:9999".parse().unwrap();
let mut event_loop = EventLoop::<MyHandler>::new().unwrap();
{
    let sock = TcpStream::connect(&addr).unwrap();
    event_loop.register(&sock, Token(0), EventSet::readable(), PollOpt::level()).unwrap();
}   // The socket is closed here, before the event loop runs
event_loop.run(&mut MyHandler).unwrap();

Таким образом, исправление состоит в том, чтобы просто связать сокет с переменной, чтобы он оставался открытым при вызове цикла обработки событий.

let addr = "127.0.0.1:9999".parse().unwrap();
let mut event_loop = EventLoop::<MyHandler>::new().unwrap();
let sock = TcpStream::connect(&addr).unwrap();
event_loop.register(&sock, Token(0), EventSet::readable(), PollOpt::level()).unwrap();
event_loop.run(&mut MyHandler).unwrap();

Ваш код ведет себя так, как вы ожидаете, и паникует, как только появляется что-то, что можно прочитать на сокете.

Другие вопросы по тегам