【问题标题】:Not accepting when handling async_accept?处理 async_accept 时不接受?
【发布时间】:2014-10-11 14:03:49
【问题描述】:

我正在尝试学习 ASIO boost,但我很难理解它。我想为应该具有可扩展性和高性能的服务器创建一个基本布局。

在以下 URL 中,有一个设置小型 TCP 服务器的示例: http://www.boost.org/doc/libs/1_42_0/doc/html/boost_asio/tutorial/tutdaytime3/src.html

我不明白的是以下部分:

void start_accept()
{
tcp_connection::pointer new_connection =
  tcp_connection::create(acceptor_.io_service());

acceptor_.async_accept(new_connection->socket(),
    boost::bind(&tcp_server::handle_accept, this, new_connection,
      boost::asio::placeholders::error));
}

void handle_accept(tcp_connection::pointer new_connection,
  const boost::system::error_code& error)
{
   if (!error)
   {
     new_connection->start();
     start_accept();
   }
}

start_accept() 最终调用 async_accept() ,它在接收数据时调用它的处理程序。 并且处理程序在完成时调用 start_accept()。

但是,如果客户端在处理程序仍在运行时尝试连接会发生什么?是不是因为 async_accept() 不再监听而无法处理请求?

如果我从错误的角度看待事情,我希望你能指出正确的方向。

【问题讨论】:

  • This answer 试图强调状态和操作之间的区别,这在学习 Boost.Asio 时可能会有所帮助。

标签: c++ networking boost boost-asio


【解决方案1】:

我认为您注意到处理程序在处理接受 (new_connection->start()) 后立即发布了一个新的 async_accept 操作:

void handle_accept(tcp_connection::pointer new_connection,
  const boost::system::error_code& error)
{
   if (!error)
   {
     new_connection->start();   // this posts connection specific asynch operations
     start_accept();            // THIS POSTS THE ASYNC OPERATION AGAIN
   }
}

您询问那里是否存在竞争条件(新的异步接受在内核接收到连接的确切时刻没有挂起)。

不存在这样的竞争,因为内核在 TCP/IP 堆栈实现中对事件进行排队。


事实上,看看传统的select/poll/epoll 方法,类似地,当套接字改变状态时,您不会收到异步信号。相反,您可以在自己的空闲时间进行投票。

内核对待处理事件的时间、缓冲区大小和数量有一些限制,因此如果您在一段时间内未能处理这些事件,它们可能会消失。

只要用户态代码不能直接控制原始硬件,那里就永远不会出现竞争条件,因为操作系统堆栈必须抽象低级 中断请求(否则您会将该操作系统称为ExoKernel)。

【讨论】:

  • 我有点明白你的意思!但我认为你可能误解了我的问题(也许那是我的错)。当 new_connection->start() 在 start_accept() 之前执行时并不是真的,但它更像是:只有在调用 async_accept 时才能接受连接。但是 async_accept 只接受 1 个连接,对吗?因此,当处理程序运行时(即使 new_connection->start() 是异步的,仍然有一点延迟,对吧?),在完成之前无法接受任何连接,并且再次调用 start_accept() 并再次到达 async_accept()。
  • 等等!我再次阅读了您的答案,我完全理解您现在的意思。因此操作系统将网络消息保留一段时间,最终当它们没有从队列中取出时,它们将被删除。这是正确的吗?因此,只要处理程序不会花费很长时间,那么小的延迟并不重要。 (因此我们可能需要用线程处理大响应吗?)作为最后一个问题!:你知道平均多长时间,例如 Windows 和 Linux 可能缓存这些?是秒还是毫秒的问题?
  • @ChristianVeenman 是的,所有代码最终都“按顺序”在任何 CPU 上运行。无论如何,没有两个事件会同时发生。但这没关系。无论如何,硬件中没有两个数据包可以同时到达。有许多层缓冲使其工作。你想要的是最小的延迟。这就是你得到的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-01
  • 1970-01-01
  • 2023-01-28
  • 1970-01-01
相关资源
最近更新 更多