boost :: asio :: tcp :: socket关闭并取消,不调用处理程序

时间:2012-05-16 22:11:26

标签: c++ boost boost-asio

我正在使用boost的asio库编写服务器。服务器使用一组Connection对象(boost :: asio :: tcp :: socket周围的包装类)处理许多并发连接。在Connection类中,不断使用socket.async_read_some(...)读取套接字,并且每当使用新数据调用读取处理程序时,立即再次调用socket.async_read_some()以读取更多数据。

现在,服务器可能由于某种原因决定断开客户端,所以自然要做的就是调用connection.close(),然后调用socket.close(),这将导致所有挂起的异步操作成为取消。这会导致使用boost :: asio :: error :: operation_aborted调用读处理程序(绑定到类Connection中的方法)。我的问题是:我不希望这种情况发生。

在socket.close()之后,我想销毁套接字和连接,然后从服务器的活动客户端列表中删除它的指针。但是,在io_service.run()的下一次迭代之前不会调用读取处理程序,这意味着我无法立即销毁我已经传递给socket.async_read_some()的套接字或读取处理程序,直到调用处理程序与错误。所以我不得不以某种方式推迟对这些物体的破坏;这太烦人了。

是否有安全的方法

  • 取消待处理的异步操作,无需调用任何处理程序,因此我可以在socket.close()或
  • 之后立即安全销毁套接字
  • 安全地知道什么时候不能再调用处理程序

或者我是以完全错误的方式接近这个?

1 个答案:

答案 0 :(得分:4)

当async.operation完成时 - 无论是成功还是出错 - 都会调用其完成处理程序。这是重要的保证,我认为尝试“破解”这种行为并不是一个好主意。 您在用例中遇到的问题通常是通过使用shared_ptr(shared_from_this idiom)来解决的:将shared_ptr<Connection>绑定到处理程序,当您获得operation_aborted(或其他一些错误)时不要发出另一个async_read,这样当完成所有处理程序后,Connection对象将被其套接字销毁。