2015-06-10 100 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); 
    } 
} 

運行此。使用類似nc localhost 1234的方式連接到它。通過使用Ctrl-C終止連接。我的代碼會認爲有新的數據可用(hint==ReadHint::data())。嘗試讀取它將導致零字節可用。

不應該暗示類似ReadHint::hup()

+0

注意:鏽蝕縮進樣式是4個空格。 –

回答

5

在mio v0.3.5上調用register的默認設置是僅爲readableInterest註冊,所以這是您將獲得的唯一提示。

如果你想被警告爲HUP,以及,你需要使用的功能register_opt,給您InterestPollOpt作爲參數,所以你的代碼變成:

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(),所以這在未來應該不成問題。