7

我正在用 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() 之后立即安全地销毁套接字,或者
  • 安全地知道何时不能调用更多的处理程序

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

4

1 回答 1

4

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

于 2012-05-17T14:13:50.420 回答