C++ Boost.Asio:socket::close不取消aysnc\u read\u some
我有一个boost套接字正在执行一个C++ Boost.Asio:socket::close不取消aysnc\u read\u some,c++,sockets,boost,boost-asio,C++,Sockets,Boost,Boost Asio,我有一个boost套接字正在执行一个async\u read\u 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)); 当我的会话类被
async\u read\u 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));
当我的会话
类被删除时,调用socket\uu()。我原以为这会取消异步读取\u some
,并调用会话::handle\u read
,但出现错误
但是,事实并非如此,请查看基本插座.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()
没有提到阅读被取消。因此,我的问题是,如何取消读取以便可以干净地关闭套接字?首先,它应该导致在调用下一个运行
、运行一个
、轮询
、或轮询
时调用句柄,前提是io服务仍处于有效状态。取消/关闭不会突然改变ASIO中调用处理程序的方式
因此,如果在删除会话
时触发此操作,您将拥有UB,因为处理程序将在已销毁的对象上调用,因为您将原始指针传递给它,该指针随后已被删除
我通常的方法是使用shared_ptr
与pimpl模式的变体相结合。我通常将实现放在一个共享指针中,并将其传递给各种ASIO调用。当外部接口被破坏时,我在pimpl上调用一个shutdown方法,这会导致ASIO取消其操作,然后接口重置其共享指针的副本
一旦ASIO调用存储的处理程序,它将不再具有共享指针的副本,销毁将完成。在我的情况下,调用接受器->关闭()
只会将操作中止错误发送到排队的接受异步和发送异步任务。我的read\u some\u async
未收到错误。
我发现调用socket->shutdown(socket\u base::shutdown\u type::shutdown\u两者)代码>和套接字->关闭()
将触发错误完成回调。您可以尝试在该套接字上关闭吗?我刚刚尝试了socket\u.shutdown(boost::asio::basic\u socket::shutdown\u type::shutdown\u两者)在调用close(如链接所示)之前,code>,但仍然不会调用会话::handle\u read
。“任何异步发送、接收或连接操作都将立即取消,并将完成boost::asio::error::operation\u aborted error。”@IgorR。这是我提出问题的理由。我想知道如何取消阅读。这很可能是我的问题的原因,所以我会给@DaveS评分。在编辑代码以消除在关闭套接字之前删除类的风险时,我注意到在关闭套接字之前,我正在对我的io\u服务
调用stop
。啊@Ne0:另一个选项是停止io_服务,并销毁所有对象。只要在关机期间不需要执行处理程序,这就可以工作。这更像是突然停机,而不是优雅停机。