【问题标题】:Boost::Asio - async_wait in async_accept handler crashes applicationBoost::Asio - async_accept 处理程序中的 async_wait 使应用程序崩溃
【发布时间】:2016-04-18 04:04:09
【问题描述】:

我目前正在尝试使用 Boost::Asio 创建一个服务器应用程序,它做了两个简单的事情:

  1. 接受客户端的传入连接
  2. 一旦客户被接受,启动一个boost::asio::deadline_timer,它会重复自己

以下代码显示了我当前的尝试:

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING

#include <WinSock2.h>
#include <Mswsock.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

using namespace boost::asio;
using namespace boost::asio::ip;

void timerHandler(const boost::system::error_code& errorCode, deadline_timer* timer) {
    timer->expires_at(timer->expires_at() + boost::posix_time::seconds(1));
    timer->async_wait(boost::bind(timerHandler, _1, timer));
}

void acceptHandler(const boost::system::error_code &errorCode, io_service *ioService) {
    deadline_timer timer(*ioService, boost::posix_time::seconds(1));
    timer.async_wait(boost::bind(timerHandler, _1, &timer));
}

int main(int argc, char** argv) {
    io_service ioService;
    tcp::socket socket(ioService);
    tcp::acceptor acceptor{ ioService, tcp::endpoint{ tcp::v4(), 12345 } };
    acceptor.listen();
    acceptor.async_accept(socket, boost::bind(acceptHandler, _1, &ioService));
    ioService.run();
    return EXIT_SUCCESS;
}

问题

计时器在acceptHandler 中无法按预期工作。不知何故,它被取消了两次,触发了一个错误,最终导致整个应用程序崩溃。

处理程序跟踪输出

@asio|1460922050.075890|0*1|socket@000000000015FAD0.async_accept
@asio|1460922051.153952|>1|ec=system:0 
@asio|1460922051.153952|1*2|deadline_timer@000000000015F608.async_wait 
@asio|1460922051.153952|1|deadline_timer@000000000015F608.cancel 
@asio|1460922051.153952|<1| 
@asio|1460922051.153952|>2|ec=system:995 
@asio|1460922051.153952|2|deadline_timer@000000000015F608.cancel

问题

  1. 是什么导致acceptHandler 取消 Handler Tracking 输出的第 4 行中的deadline_timer?
  2. 处理程序跟踪输出的第 6 行中的错误 995 是什么原因造成的?错误消息是:由于线程退出或应用程序请求,I/O 操作已中止

  3. 什么原因导致timerHandler取消Handler Tracking输出第7行的deadline_timer?

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    timeracceptHandler 的堆栈上分配,因此在调用timerHandler 时无效。您需要动态分配计时器。

    此外,您应该检查两个处理程序中的错误代码。当您想结束程序并cancel 计时器时,这一点尤其重要。

    【讨论】:

    • 多么愚蠢的错误。谢谢你。为了简单起见,我在这里留下了错误检查。我通常在所有处理程序中使用 switch-cases。
    猜你喜欢
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多