Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Boost.Asio:socket::close不取消aysnc\u read\u some_C++_Sockets_Boost_Boost Asio - Fatal编程技术网

C++ Boost.Asio:socket::close不取消aysnc\u read\u some

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)); 当我的会话类被

我有一个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));
当我的
会话
类被删除时,调用
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两者),但仍然不会调用
会话::handle\u read
。“任何异步发送、接收或连接操作都将立即取消,并将完成boost::asio::error::operation\u aborted error。”@IgorR。这是我提出问题的理由。我想知道如何取消阅读。这很可能是我的问题的原因,所以我会给@DaveS评分。在编辑代码以消除在关闭套接字之前删除类的风险时,我注意到在关闭套接字之前,我正在对我的
io\u服务
调用
stop
。啊@Ne0:另一个选项是停止io_服务,并销毁所有对象。只要在关机期间不需要执行处理程序,这就可以工作。这更像是突然停机,而不是优雅停机。