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

jlh*_*jlh 6 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()之后立即安全地销毁套接字,或者
  • 安全地知道什么时候不能再调用处理程序

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

Igo*_* R. 4

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