0

我有一个升压插座在做async_read_some

socket_.async_read_some(boost::asio::buffer(data_, max_length),
    boost::bind(&Session::handle_read, this,
    boost::asio::placeholders::error,
    boost::asio::placeholders::bytes_transferred));

当我的Session类被删除时socket_.close()被调用。我认为这会取消async_read_someand 调用Session::handle_read并出现错误。

然而事实并非如此,查看basic_socket.hpp

/// Close the socket.
/**
* This function is used to close the socket. Any asynchronous send, receive
* or connect operations will be cancelled immediately, and will complete
* with the boost::asio::error::operation_aborted error.
*
* @throws boost::system::system_error Thrown on failure. Note that, even if
* the function indicates an error, the underlying descriptor is closed.
*
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
*/
void close()

没有提到读取被取消。所以我的问题是,如何取消读取以便我可以干净地关闭套接字?

4

2 回答 2

2

首先,它应该导致在调用 next runrun_onepoll或时调用句柄poll_one,假设io_service仍然处于有效状态。取消/关闭不会突然改变在 ASIO 中调用处理程序的行为。

因此,如果您在删除 时触发此操作Session,您将拥有 UB,因为将在销毁的对象上调用处理程序,因为您将原始指针传递给它,该指针随后已被删除。

我通常的技术是shared_ptr结合使用 pimpl 模式的变体。我通常在共享指针中实现,并将其传递给各种 ASIO 调用。当外部接口被破坏时,我在 pimpl 上调用一个关闭方法,这会导致 ASIO 取消其操作,然后接口重置其共享指针的副本。

一旦 ASIO 调用存储的处理程序,它将不再拥有共享指针的副本,并且销毁将完成。

于 2013-09-10T11:49:21.560 回答
0

就我而言,调用acceptor->close()只会将 operation_aborted 错误发送到队列accept_asyncsend_async任务。我read_some_async的没有收到错误。我发现调用socket->shutdown(socket_base::shutdown_type::shutdown_both);socket->close();会触发错误完成回调。

于 2019-08-30T22:01:46.553 回答