rust - 如何防止 TcpStream 阻塞读取?

标签 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,我该如何处理这种情况?

最佳答案

您想使用 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
                },
            };
        }
    }
}

关于rust - 如何防止 TcpStream 阻塞读取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33557375/

相关文章:

linked-list - 为什么拆分 Rust 的 std::collections::LinkedList O(n)?

rust - 如果我在代码的各个位置使用了非可变变量,为什么会出现借来的错误?

rust - 无法使用 #[tokio::main] 宏运行两个线程

rust - 如何修复错误 "the trait ` OutputType` 未针对 `time::OffsetDateTime` 实现”?

rust - struct 字段中 Rng 的 Vec,不能借用不可变字段作为可变字段

arrays - 如何在Rust中将数字字符串转换为整数数组或整数向量?

rust - 如何使用 Arc<Mutex<...>> 转换特征对象?

rust - 当 Rust 结构包含生命周期特征时会发生什么?

rust - 从使用 Box<Trait> 转换的结构访问字段

random - Rust:使用 gen_range 模拟 rand 函数