如何使用 Tokio TcpListener 处理 WouldBlock 错误?
How to deal with WouldBlock error with a Tokio TcpListener?
考虑以下代码:
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 的库。您从不想要在异步事件循环中执行阻塞操作。
相反,要么 all-in 使用异步,要么完全避免它并使用更简单、更粗糙的线程。
Tokio 的 io::read_to_end
创建了一个能够从套接字读取所有数据的未来:
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(())
}),
);
}
另请参阅:
- Why would the first write to Mio's TcpStream after accepting give an "operation would block" error?
考虑以下代码:
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 的库。您从不想要在异步事件循环中执行阻塞操作。
相反,要么 all-in 使用异步,要么完全避免它并使用更简单、更粗糙的线程。
Tokio 的 io::read_to_end
创建了一个能够从套接字读取所有数据的未来:
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(())
}),
);
}
另请参阅:
- Why would the first write to Mio's TcpStream after accepting give an "operation would block" error?