如何防止TcpStream在读取时阻塞?

时间:2015-11-06 00:26:37

标签: rust

let listener = TcpListener::bind("localhost:1234").unwrap();
for stream in listener.incoming() {
    let s = stream.unwrap();
    handle_stream(s);
}   

fn handle_stream(mut stream: TcpStream) -> () {
    let mut buf = [0];
    loop {
        let _ = match stream.read(&mut buf) {
            Err(e) => panic!("Got an error: {}", e),
            Ok(m) => {
                println!("Received {:?}, {:?}", m, buf);
                if m == 0 {
                     // doesn't reach here.
                     break;
                }
                m
            },
        };
    }
}

然后我通过运行curl http://localhost:1234连接到服务器。

我希望会返回Ok(0),但它不会到达该语句而是会挂起。如果这是一个EOF,在这种情况下我该如何对待?

1 个答案:

答案 0 :(得分:4)

您想使用TcpStream::set_read_timeout,然后检查该特定类型的错误:

use std::io::{self, Read};
use std::net::{TcpListener, TcpStream};
use std::time::Duration;

fn main() {
    let listener = TcpListener::bind("localhost:1234").unwrap();
    for stream in listener.incoming() {
        let s = stream.unwrap();
        handle_stream(s);
    }

    fn handle_stream(mut stream: TcpStream) -> () {
        let mut buf = [0];
        stream.set_read_timeout(Some(Duration::from_millis(100))).unwrap();
        loop {
            let _ = match stream.read(&mut buf) {
                Err(e) => {
                    match e.kind() {
                        io::ErrorKind::WouldBlock => {
                            println!("would have blocked");
                            break;
                        },
                        _ => panic!("Got an error: {}", e),
                    }
                },
                Ok(m) => {
                    println!("Received {:?}, {:?}", m, buf);
                    if m == 0 {
                        // doesn't reach here.
                        break;
                    }
                    m
                },
            };
        }
    }
}