繁体   English   中英

Boost.Asio async_handshake无法取消

[英]Boost.Asio async_handshake cannot be canceled

当使用Boost Asio SSL流启动async_handshake ,然后在握手完成之前实现截止期限计时器以取消/关闭流时,该程序将崩溃并出现缓冲区溢出异常(在Windows上,我还没有尝试过Linux)。 崩溃发生在套接字close d之后,外部处理程序完成执行,但在run()命令完成之前。

进行SSL握手时,为什么无法关闭套接字? 还是这是Boost Asio中的错误?

class Connection
{
    void connect_handler(const boost::system::error_code &err)
    {
        ...
        ssock->async_handshake(boost::asio::ssl::stream_base::client,
                   boost::bind(&Connection::handle_handshake, this, _1));
        ...
    }

    void handle_handshake(const boost::system::error_code &err)
    {
        // CONNECTED SECURELY
    }

    void handle_timeout()
    {
        // HANDLE SSL SHUTDOWN IF ALREADY CONNECTED...
        ...
        ssock->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
        ssock->close();
        delete ssock;
    }

    ...

    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> *ssock;
};

为了澄清,称handle_timeout()之前handle_handshake()是由IO服务,即会在崩溃io_service::run()方法。

问题是套接字对象在异步处理程序完成之前已被销毁。 要取消待处理/排队的处理程序,请使用io_service::stop()如下所示:

io_service.stop(); // Stop the IO service to prevent handlers from executing
ssock->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
ssock->close();
delete ssock;

所以不,这不是Boost.Asio本身的错误。

我们也碰到了那个。 我的同事(AW)发现了罪魁祸首。 握手在后台使用读写操作,这些操作需要取消,并且握手操作需要正确完成(带有operation_aborted错误),然后才能安全地关闭袜子。 经过测试的解决方案如下:

void handle_timeout() {
  ...

  // cancel pending read/write operations
  ssock->lowest_layer().cancel();

  // finish shutdown on next tick of event loop
  boost::asio::post([=] {
    ssock->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
    ssock->close();
    delete ssock;
  });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM