Boost.Asio deadline_timer没有按预期工作

时间:2012-03-28 22:46:03

标签: c++ boost boost-asio

我正在尝试在TCP套接字上实现Boost.Asio读取的超时。

我正在尝试将async_read_somedeadline_timer一起使用。我下面的函数是一个类的成员,该类包含一个指向TCP套接字和io_service的智能指针。当在没有返回任何数据的活动套接字上调用时,期望会发生等待2秒并返回false

会发生什么:如果套接字永远不会返回任何数据,它会按预期工作。然而,如果服务器返回数据,则继续调用下面的方法立即返回,因为调用定时器回调而不等待两秒钟。

我尝试评论async_read_some调用,该函数始终按预期工作。为什么async_read_some会改变计时器的工作方式?

    client::client() {
        // Init socket and timer
        pSock = boost::shared_ptr<tcp::socket > (new tcp::socket(io_service));
    }

bool client::getData() {

              // Reset io_service
                io_service.reset(); 

                // Init read timer
                boost::asio::deadline_timer timer(pSock->io_service());
                timer.expires_from_now(boost::posix_time::seconds(2)); 
                timer.async_wait(boost::bind(&client::read_timeout, this, boost::system::error_code(), true));


    //            // Async read the data
                pSock->async_read_some(boost::asio::buffer(buffer_),
                        boost::bind(&client::read_complete,
                        this,
                        boost::asio::placeholders::error,
                        boost::asio::placeholders::bytes_transferred
                        ));



                // While io_service runs check read result 
                while (pSock->io_service().run_one()) {
                    if (m_read_result > 0) {
                        // Read success 
                        return m_read_result;
                    }else if(m_read_result < 0){
                        return false;
                    }
                }
            }
}



void client::read_complete(const boost::system::error_code& error, size_t bytes_transferred) {
    if (!error) {
        m_read_result = bytes_transferred;
    }else{
        m_read_result = -1;
    }
}

void client::read_timeout(const boost::system::error_code& error, bool timeout) {
    if(!error){
        m_read_result = -1;
    }
}

2 个答案:

答案 0 :(得分:1)

设置定时器时的简单问题boost :: system :: error_code()应更改为_1或error :: placeholder

timer.async_wait(boost::bind(&client::read_timeout, this, _1, true));

答案 1 :(得分:0)

检查连接错误时,您已取消了条件。

应该是:

if(error){
    std::cout  << "read_timeout Error - " << error.message() << std::endl;
}

现在您将看到,使用错误代码boost::asio::error::operation_aborted调用回调。

这是因为,当您收到任何数据时,您从函数getData返回,而deadline_timer的析构函数会调用带有错误代码集的回调。