我正在编写一个网关服务,它监听网络套接字并将接收到的数据包路由到单独的守护进程。我打算使用 boost asio,但我遇到了几个问题。这是我计划实现的服务器的设计:
网关中的每个描述符都是非阻塞的。
我遇到了一个特殊问题,当网关写入服务连接时,如果服务套接字已满,则有可能出现 EAGAIN 或 EWOULDBLOCK 错误。我计划通过排队缓冲区和“等待服务连接准备好写入”来解决这个问题。
如果我要使用 select 系统调用“等待服务连接准备好写入”将转换为在 writefd 列表中添加 fd 并将其传递给 select。一旦服务连接准备好写入,我会将排队的缓冲区写入连接,并将从 select 的 writefdlist 中删除服务连接。
我如何用 boost asio 做同样的事情?这样的事情可能吗?
最佳答案
如果您想采用这种方法,请使用 boost::asio::null_buffers
启用 Reactor-Style operations .此外,通过 socket::non_blocking()
将 Boost.Asio 套接字设置为非阻塞。成员函数。此选项将同步套接字操作设置为非阻塞。这与将 native 套接字设置为非阻塞不同,因为 Boost.Asio 将 native 套接字设置为非阻塞,并模拟同步操作的阻塞。
然而,如果 Proactor-Style 操作是一个选项,那么考虑使用它们,因为它允许应用程序忽略一些较低级别的细节。当使用前摄器样式操作时,Boost.Asio 将代表应用程序执行 I/O,正确处理 EWOULDBLOCK
, EAGAIN
, 和 ERROR_RETRY
逻辑。例如,当 Boost.Asio 发生前面提到的错误之一时,它会将 I/O 操作推回其内部队列,推迟重新尝试,允许尝试其他操作。
通常,有两个约束需要使用 Reactor-Style 操作而不是 Proactor-Style 操作:
关于sockets - 将套接字描述符动态添加到 io_service 并将其删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15286939/