当使用 Boost Asio SSL 流启动 async_handshake
,然后在握手完成之前实现截止时间计时器以取消/关闭流时,程序将因缓冲区溢出异常而崩溃(在 Windows 上,我还没有尝试过 Linux)。崩溃发生在套接字关闭
之后,外部处理程序完成执行,但在 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;
};
澄清一下,在 IO 服务调用 handle_handshake()
之前调用 handle_timeout()
将在 io_service::run()
方法。
我们也遇到过这种情况。我的同事 (AW) 发现了那个罪魁祸首。握手在后台使用读写操作,这些操作需要取消,握手操作需要正确完成(出现 operation_aborted 错误),然后才能安全关闭 ssock。经过测试的解决方案如下:
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;
});
}
我是一名优秀的程序员,十分优秀!