考虑以下代码:

extern crate tokio; // Executor runtime

use tokio::prelude::*;
use tokio::net::TcpListener;
use std::net::SocketAddr;

fn main() {
    let addr = "127.0.0.1:8118".parse::<SocketAddr>().unwrap();
    let listener = TcpListener::bind(&addr)
        .expect("unable to bind TCP listener");
    tokio::run(listener.incoming()
        .map_err(|e| eprintln!("failed to accept socket; error = {:?}", e))
        .for_each(|mut socket| {
            let mut buf = vec![];
            socket.read_to_end(&mut buf).unwrap();
            println!("Received: {:#?}", buf);
            Ok(())
        })
    );
}

当我运行此命令并将其发送到端口8118时,出现以下错误:

thread 'tokio-runtime-worker-0' panicked at 'called `Result::unwrap()` on an `Err` value: Kind(WouldBlock)', src/libcore/result.rs:997:5

我想象有某种方法可以将套接字置于阻塞模式,或者捕获错误并对其进行处理。我想知道解决这个问题的标准,规范方法是什么。

我宁愿不阻止,因为我希望服务器在等待客户端时做其他事情,所以异步/线程解决方案将是很棒的。

最佳答案

您正在使用Tokio,该库的全部目的是启用异步IO。您永远都不想在异步事件循环中执行阻塞操作。

相反,要么全力投入异步,要么完全避免异步,并使用更简单,更粗糙的线程。

Tokio的 io::read_to_end 创造了一个能够从套接字读取所有数据的 future :

use std::net::SocketAddr;
use tokio::{net::TcpListener, prelude::*}; // 0.1.22

fn main() {
    let addr = "127.0.0.1:8118".parse::<SocketAddr>().unwrap();
    let listener = TcpListener::bind(&addr).expect("unable to bind TCP listener");

    tokio::run(
        listener
            .incoming()
            .and_then(|s| tokio::io::read_to_end(s, vec![]))
            .map_err(|e| panic!("failed: {:?}", e))
            .for_each(|(_socket, buf)| {
                println!("Received: {:#?}", buf);
                Ok(())
            }),
    );
}

也可以看看:
  • How do I prevent TcpStream from blocking on a read?
  • Why would the first write to Mio's TcpStream after accepting give an "operation would block" error?
  • What is the standard way to get a Rust thread out of blocking operations?
  • What is the best approach to encapsulate blocking I/O in future-rs?
  • Why does Future::select choose the future with a longer sleep period first?
  • 关于rust - 如何使用Tokio TcpListener处理WouldBlock错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56916161/

    10-10 18:33