如何实现异步版本的TcpStream::connect()?

问题描述 投票:0回答:1

我正在学习异步运行时并尝试编写运行时和 TcpStream 的异步版本。

我已经完成了

accept()
write()
read()
,只需调用
std::TcpStream
的相应函数并处理
Error:WouldBlocking
错误(将其注册到Event-Poller上)。

但是,我不知道如何实施

connect()
。对于前面的功能,已经有一个
TcpStream
,如果待处理,我可以在事件轮询器上注册它。但对于
connect()
来说,如果
std::TcpStream::connect()
待定,则不存在这样的TcpStream。因为它将
socket(2)
connect(2)
合并在里面。

我查看了

Async::connect()
crate中
async-io
的源代码,它针对不同的操作系统直接调用低级函数(例如socket(2)、connect(2))。我是否必须做同样的事情(我不想做)?

asynchronous rust async-await
1个回答
0
投票

这是您在这里为自己设定的一项艰巨的任务。

async-io
tokio
受欢迎是有原因的;自己写这些东西既乏味又容易出错。

您可能知道异步是如何工作的,您知道轮询套接字并返回“Poll::Pending”并不难。困难的部分是检测套接字不再挂起并且可以再次轮询。

通常有两种方法:

  • 生成一个同步等待数据的线程,然后通知唤醒者
  • 注册某种在新数据到达时调用的中断

第二种解决方案高度依赖平台,但性能应该更好;这就是为什么

async-io
和类似的人选择这条道路。

如果您只是将其用作编程练习并且不需要高性能,那么第一个解决方案可能是您应该选择的解决方案:

  • 与普通同步api连接
  • 将socket拆分成读写部分
  • 生成一个线程,从读取的部分读取数据
  • 将读取的数据放入某种类型的通道中,例如
    futures-channel
    crossbeam
  • 使用此通道从套接字异步读取
  • 写入套接字时,要么对另一个线程执行相同的操作,要么使用类似
    spawn_blocking
    的机制。始终确保您不会从异步任务中调用阻塞函数。

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.