如何在 block_on 部分交换数据?
How to exchange data in a block_on section?
我正在学习 Rust 和 Tokio,我怀疑我可能走错了方向。
我正在尝试打开到远程服务器的连接并执行握手。我想使用非阻塞 IO,所以我正在使用 Tokio 的线程池。握手需要快速执行,否则遥控器将关闭套接字,因此我试图将消息交换链接到单个 block_on 部分:
let result: Result<(), Box<dyn std::error::Error>> = session
.runtime()
.borrow_mut()
.block_on(async {
let startup = startup(session.configuration());
stream.write_all(startup.as_ref()).await?;
let mut buffer:Vec<u8> = Vec::new();
let mut tmp = [0u8; 1];
loop {
let total = stream.read(&mut tmp).await;
/*
if total == 0 {
break;
}
*/
if total.is_err() {
break;
}
buffer.extend(&tmp);
}
Ok(())
});
我的问题是当套接字中没有更多字节可供读取时该怎么办。我当前的实现读取响应并在最后一个字节挂起后,我相信是因为套接字未关闭。我认为检查读取的 0 个字节就足够了,但是对 read() 的调用从来没有 returns.
处理此问题的最佳方法是什么?
来自您的评论:
Nope, the connection is meant to remain open.
如果您从打开的连接读取,读取将阻塞直到有足够的字节满足它或另一端关闭连接,类似于阻塞读取在 C 中的工作方式。Tokio 正在工作 as-intended .
如果关闭流并不表示消息结束,那么您将必须自行决定何时停止读取并开始处理。一种简单的方法是在请求前加上一个长度前缀,并且只读取那么多字节。
请注意,无论您使用什么 API,都必须执行上述操作。您是否使用 tokio 并不能真正回答“消息何时结束”这一基本问题。
我正在学习 Rust 和 Tokio,我怀疑我可能走错了方向。
我正在尝试打开到远程服务器的连接并执行握手。我想使用非阻塞 IO,所以我正在使用 Tokio 的线程池。握手需要快速执行,否则遥控器将关闭套接字,因此我试图将消息交换链接到单个 block_on 部分:
let result: Result<(), Box<dyn std::error::Error>> = session
.runtime()
.borrow_mut()
.block_on(async {
let startup = startup(session.configuration());
stream.write_all(startup.as_ref()).await?;
let mut buffer:Vec<u8> = Vec::new();
let mut tmp = [0u8; 1];
loop {
let total = stream.read(&mut tmp).await;
/*
if total == 0 {
break;
}
*/
if total.is_err() {
break;
}
buffer.extend(&tmp);
}
Ok(())
});
我的问题是当套接字中没有更多字节可供读取时该怎么办。我当前的实现读取响应并在最后一个字节挂起后,我相信是因为套接字未关闭。我认为检查读取的 0 个字节就足够了,但是对 read() 的调用从来没有 returns.
处理此问题的最佳方法是什么?
来自您的评论:
Nope, the connection is meant to remain open.
如果您从打开的连接读取,读取将阻塞直到有足够的字节满足它或另一端关闭连接,类似于阻塞读取在 C 中的工作方式。Tokio 正在工作 as-intended .
如果关闭流并不表示消息结束,那么您将必须自行决定何时停止读取并开始处理。一种简单的方法是在请求前加上一个长度前缀,并且只读取那么多字节。
请注意,无论您使用什么 API,都必须执行上述操作。您是否使用 tokio 并不能真正回答“消息何时结束”这一基本问题。