sockets - 将套接字描述符动态添加到 io_service 并将其删除

标签 sockets network-programming boost-asio

我正在编写一个网关服务,它监听网络套接字并将接收到的数据包路由到单独的守护进程。我打算使用 boost asio,但我遇到了几个问题。这是我计划实现的服务器的设计:

  • 网关将使用 boost asio 监听 TCP 连接。
  • 网关还将使用 boost asio 监听来自守护程序的流式 Unix 域连接。
  • 每当 tcp 连接上有数据包时,网关会查看数据包中的协议(protocol)标记,并将数据包放在服务将监听的 unix 域连接上。
  • 每当服务连接上有数据包时,网关就会查看客户端标签并建立相应的客户端连接。

  • 网关中的每个描述符都是非阻塞的。

    我遇到了一个特殊问题,当网关写入服务连接时,如果服务套接字已满,则有可能出现 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 操作:

  • 另一个库希望自己执行 I/O 操作。
  • 内存限制。使用 Proactor,缓冲区的生命周期必须超过读取或写入操作的持续时间,并且并发操作可能需要自己的缓冲区。 Reactor 允许缓冲区的生命周期从准备好读取数据时开始,并在不再使用数据时结束。
  • 关于sockets - 将套接字描述符动态添加到 io_service 并将其删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15286939/

    相关文章:

    Python:如何等到子进程完成初始化

    c++ - 用 C++ 设计一个 ipstack

    c++ - 使用 OpenSSL boost ASIO 无法读取 HTTP header

    Java套接字连接

    django - 为什么我可以连接到http ://127. 0.0.1 :8000/but not to http://192. 168.1.6/

    vbscript - 使用 WMI 确定哪些适配器连接到互联网

    c++ - 高效的数据包类型/传输协议(protocol)

    c++ - boost asio 打开更多的一个套接字

    ruby - 如何使用 ruby​​ 读取恒定的 NMEA http 数据流

    tcp - 协议(protocol) header 中的十六进制值