2015-06-10 2 views
4

При использовании MIO (0.3.5), как определить прекращение соединения?Обнаружение зависания клиента в MIO

Я попытался следующие:

extern crate mio; 
use mio::{EventLoop,Token,ReadHint}; 
use std::io::Read; 

fn main(){ 
    let listener = mio::tcp::TcpListener::bind("localhost:1234").unwrap(); 
    let (stream,_) : (mio::tcp::TcpStream, _) = listener.accept().unwrap(); 

    let mut event_loop = EventLoop::new().unwrap(); 
    event_loop.register(&stream,Token(0)).unwrap(); 
    println!("run..."); 
    event_loop.run(&mut H{stream:stream}).unwrap(); 
} 

struct H{stream : mio::tcp::TcpStream} 

impl mio::Handler for H{ 
    type Timeout =(); 
    type Message =(); 

    fn readable(&mut self, _ : &mut EventLoop<Self>, _ : Token, hint: ReadHint){ 
    let mut buf: [u8; 500] = [0; 500]; 
    println!("{} {}",(hint==ReadHint::data()),self.stream.read(&mut buf).unwrap()); 
    std::thread::sleep_ms(1000); 
    } 
} 

Run этого. Подключайтесь к нему, используя что-то вроде nc localhost 1234. Завершите соединение с помощью Ctrl-C. Мой код будет считать, что есть новые данные (hint==ReadHint::data()). Попробуйте прочитать это приведет к нулю нулевых байтов.

Разве подсказка не должна быть чем-то вроде ReadHint::hup()?

+0

Примечание: стиль отступа от ржавчины - это 4 пробела. –

ответ

5

По умолчанию при вызове register на mio v0.3.5 необходимо зарегистрироваться только для readableInterest, так что это единственный намек, который вы получите.

Если вы хотите быть предупрежден за HUP, а также, вам нужно использовать функцию register_opt и дайте Interest и PollOpt, как параметры, так что ваш код становится:

extern crate mio; 
use mio::{EventLoop,Token,ReadHint,PollOpt,Interest}; 
use std::io::Read; 

fn main() { 
    let listener = mio::tcp::TcpListener::bind("localhost:1234").unwrap(); 
    let (stream,_) : (mio::tcp::TcpStream, _) = listener.accept().unwrap(); 

    let mut event_loop = EventLoop::new().unwrap(); 
    let interest = Interest::readable() | Interest::hup(); 
    event_loop.register_opt(&stream,Token(0), interest,PollOpt::level()).unwrap(); 
    println!("run..."); 
    event_loop.run(&mut H{stream:stream}).unwrap(); 
} 

struct H{stream : mio::tcp::TcpStream} 

impl mio::Handler for H { 
    type Timeout =(); 
    type Message =(); 

    fn readable(&mut self, event_loop : &mut EventLoop<Self>, _ : Token, hint: ReadHint){ 
     let mut buf: [u8; 500] = [0; 500]; 
     if hint.is_hup() { 
      println!("Recieved hup, exiting"); 
      event_loop.shutdown(); 
      return; 
     } 
     println!("{} {}",hint.is_data(),self.stream.read(&mut buf).unwrap()); 
     std::thread::sleep_ms(1000); 
    } 
} 

Я думаю, что по умолчанию для удобства функция register изменилась в v0.4.0 на Interest::all(), поэтому это не должно быть проблемой в будущем.

Смежные вопросы