c++ - 断开连接后正确杀死 asio steady_timer

标签 c++ ssl asio

我使用独立的 asio 编写了一个异步 SSL 套接字实现,并且在服务器重置/关闭连接后努力让它重新连接。我是 asio 库的新手,所以请多多包涵。

由于 steady_timer,调用 io_context::run 的线程即使在断开连接后仍保持阻塞状态。我的 close() 逻辑负责重置套接字资源,还负责尝试终止计时器。这就是我的代码现在的样子:

创建我的异步作业:

timer.async_wait(std::bind(&ssl_socket::heartbeat, this));

在我的close() 方法中:

timer.expires_at(std::chrono::steady_clock::now());
timer.cancel();

根据boost docs , cancel() 应该:

Cancel any asynchronous operations that are waiting on the timer.

也许我误解了这一点,但我想这也会取消绑定(bind)到 io_context 的异步作业,但事实并非如此。 io_context::run 永远不会被释放并造成死锁。

这是我的计时器处理程序的样子:

void ssl_socket::heartbeat() {
    spdlog::get("console")->trace("heartbeat called");

    if (connected_) {
        write(heartbeat_token);
        spdlog::get("console")->trace("heartbeat sent");
    }

    timer.expires_at(std::chrono::steady_clock::now() + std::chrono::seconds(heartbeat_interval));
    timer.async_wait(std::bind(&ssl_socket::heartbeat, this));

}

我想让处理程序不必验证它是否应该更新其计时器并让 close() 处理它(如果可能)。

最佳答案

您忽略了错误代码。

According to the boost docs, cancel() should:

Cancel any asynchronous operations that are waiting on the timer.

这有点误导。当您阅读 cancel 函数的完整描述时,您会看到:

This function forces the completion of any pending asynchronous wait operations against the timer. The handler for each cancelled operation will be invoked with the boost::asio::error::operation_aborted error code.

这意味着,您的处理程序将被取消函数调用,并且由于您的处理程序只是重新设置到期时间并再次等待,因此循环永远不会结束。您需要检查错误代码,如果已设置,则跳出循环。

if(error) return;

关于c++ - 断开连接后正确杀死 asio steady_timer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55784866/

相关文章:

C++WinApi : GetClientRect fails

c# - 标题栏的上下文菜单

java - 使用 SSL 客户端证书加密 HTTP 请求中的数据

django - 我如何获得 ssl 证书以使用我的 django 应用程序

c# - 如何使用 AsioOut 进行 NAudio 录音和播放

c++ - 我对C++ boost::asio和std::async有疑问

c++ - 制作 C++ 哈希表的最佳策略,线程安全

php - 在不同域上测试 PayPal 证书

c++ - asio 分配示例中的 ‘typename’ 是什么意思

c++ - C++0x 的哪些功能肯定会保留(如果有的话)?