Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 向io_服务动态添加套接字描述符并将其删除_Sockets_Network Programming_Boost Asio - Fatal编程技术网

Sockets 向io_服务动态添加套接字描述符并将其删除

Sockets 向io_服务动态添加套接字描述符并将其删除,sockets,network-programming,boost-asio,Sockets,Network Programming,Boost Asio,我正在编写一个网关服务,它侦听网络套接字并将接收到的数据包路由到单独的守护进程。我计划使用boost asio,但我有几个问题要问。以下是我计划实施的服务器的设计: 网关将使用boost asio侦听TCP连接 网关还将使用boost asio侦听来自守护进程的流式Unix域连接 只要tcp连接上有数据包,网关就会查看数据包中的协议标记,并将数据包放在服务将侦听的unix域连接上 每当服务连接上有一个数据包时,网关就会查看客户机标记并打开相应的客户机连接 网关中的每个描述符都是非阻塞描述符 我遇

我正在编写一个网关服务,它侦听网络套接字并将接收到的数据包路由到单独的守护进程。我计划使用boost asio,但我有几个问题要问。以下是我计划实施的服务器的设计:

  • 网关将使用boost asio侦听TCP连接

  • 网关还将使用boost asio侦听来自守护进程的流式Unix域连接

  • 只要tcp连接上有数据包,网关就会查看数据包中的协议标记,并将数据包放在服务将侦听的unix域连接上

  • 每当服务连接上有一个数据包时,网关就会查看客户机标记并打开相应的客户机连接

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

    我遇到了一个特殊的问题,当网关写入服务连接时,如果服务套接字已满,则有可能出现EAGAIN或EWOOLDLOCK错误。我计划通过排队缓冲区和“等待服务连接准备写入”来解决这个问题

    如果我使用select系统调用,“等待服务连接准备写入”将转换为在writefd列表中添加fd并将其传递给select。一旦服务连接准备好写入,我将把排队的缓冲区写入连接,并将从select的writefdlist中删除服务连接


    如何对boost asio执行相同的操作?这可能吗

    使用boost::asio,您不需要干扰非阻塞模式和/或返回代码,如EAGAIN-ewoodblock等。此外,您也不需要“向池循环添加套接字”之类的东西;这对您来说是隐藏的,因为它是一个更高级的框架

    典型的模式是

  • 您可以创建io_服务对象
  • 创建绑定到io_服务的套接字
  • 在套接字上创建一些异步事件(异步连接、异步读取、异步写入等)
  • 您可以使用io_service::run或类似方法运行调度
  • asio将在时机成熟时触发您的处理程序

  • 查看boost::asio页面上的。我认为可以为您的任务演示技术。

    如果多个线程将写入用于连接的同一个套接字对象,那么您需要使用互斥锁(或关键部分,如果使用Windows)来对代码执行单线程操作


    至于“当网关写入服务连接时,如果服务套接字已满,则有可能出现EAGAIN或EWOLDBLOCK错误”,我相信ASIO会在内部为您处理该错误,因此您不必担心。如果您想使用该方法,请使用启用。此外,通过member函数将Boost.Asio套接字设置为非阻塞。此选项将同步套接字操作设置为非阻塞。这与将本机套接字设置为非阻塞、设置为Boost不同。Asio将本机套接字设置为非阻塞,并模拟同步操作的阻塞

    但是,如果Pro Actudio风格操作是一个选项,那么考虑使用它们,因为它允许应用程序忽略一些较低级别的细节。使用proactor风格的操作时,Boost.Asio将代表应用程序执行I/O,正确处理

    eWoldBlock
    EAGAIN
    ERROR\u RETRY
    逻辑。例如,当Boost.Asio出现前面提到的错误时,它会将I/O操作推回其内部队列,推迟重新尝试,允许尝试其他操作

    通常情况下,有两种约束要求使用反应器式操作,而不是前置器式操作:

    • 另一个库希望自己执行I/O操作
    • 内存限制。对于前置器,缓冲区的寿命必须超过读或写操作的持续时间,并发操作可能需要自己的缓冲区。反应器允许缓冲区的生命周期从数据准备好读取时开始,到数据不再使用时结束

    我同意,我不应该关心EAGAIN或EWOODBLOCK,这正是asio的用意,但写入处理程序不会因为套接字随时准备写入而被不断调用吗?在我的情况下,这里的服务连接将始终准备好写入,并导致一个繁忙的循环。@RavikumarTulugu no.当作业完成或完全失败时(例如,取消或断开对等连接),将调用处理程序。调用write_处理程序后,asio将忘记它,因为写入作业已经完成。当您需要写入下一个数据块时,需要再次调用async_write。因此,当您可以编写时,不会调用处理程序,而是在asio完成您的任务时调用它。+1很好的摘要或可能需要reactor模式的原因