问题描述
我正在学习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()的调用再也不会返回。
处理此问题的最佳方法是什么?
解决方法
根据您的评论
不,该连接应保持打开状态。
如果您从打开的连接中读取数据,则读取将一直阻塞,直到有足够的字节满足该请求,或者另一端关闭连接为止,类似于阻塞读取在C语言中的工作方式。Tokio按预期工作。
如果关闭流并不表示消息已结束,那么您将必须做自己的工作来弄清楚何时停止阅读并开始处理。一种简单的方法是在请求前加上一个长度,然后只读取那么多字节。
请注意,无论您使用哪种API,都必须执行上述操作。是否使用tokio的事实并不能真正回答“消息何时传递”这一基本问题。