簡體   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