在async_accept处理程序中的Boost :: Asio - async_wait会导致应用程序崩溃

时间:2016-04-17 19:55:59

标签: c++ boost-asio

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

  1. 接受客户端的传入连接
  2. 接受客户端后,启动boost::asio::deadline_timer重复自身
  3. 以下代码显示了我当前的尝试:

    #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取消处理程序跟踪输出第4行中的deadline_timer?
    2. 处理程序跟踪输出第6行中的错误995是什么?错误消息是:由于线程退出或应用程序请求而导致I / O操作中止

    3. 是什么导致timerHandler取消处理程序跟踪输出的第7行中的deadline_timer?

1 个答案:

答案 0 :(得分:3)

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

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