如何使用boost :: asio :: read_some实现超时?

时间:2011-11-04 18:27:48

标签: c++ boost boost-asio

我们可以在插座上读一下像这样的东西:

#include <boost/asio.hpp>
#include <boost/optional.hpp>

//...

void http_request::set_result(boost::optional<boost::system::error_code>* a, boost::system::error_code b) 
{ 
    a->reset(b); 
} 
template <typename MutableBufferSequence> 
void read_with_timeout(boost::asio::ip::tcp::socket& sock, 
    const MutableBufferSequence& buffers) 
{ 
    boost::optional<boost::system::error_code> timer_result; 
    boost::asio::deadline_timer timer(sock.io_service()); 
    timer.expires_from_now(seconds(1)); 
    timer.async_wait(boost::bind(set_result, &timer_result, _1)); 
    boost::optional<boost::system::error_code> read_result; 
    async_read(sock, buffers, 
        boost::bind(set_result, &read_result, _1)); 

    sock.io_service().reset(); 
    while (sock.io_service().run_one()) 
    { 
        if (read_result) 
            timer.cancel(); 
        else if (timer_result) 
            sock.cancel(); 
    } 
    if (*read_result) 
        throw std::system_error(*read_result); 
}

如图here所示。我想知道是否有可能以及如何在这样的时尚中实现有时间的read_some(我们在那里跟踪时间unteel第一个符号)?或者可以将reead_some_unteel与计时器一起使用吗?

1 个答案:

答案 0 :(得分:2)

我认为您可以使用大部分相同的代码,只需将socket替换为async_read。async_read_some并调整您传递的参数作为ReadHandler async_read_some

#include <boost/asio.hpp>
#include <boost/optional.hpp>

//...

void http_request::set_result(boost::optional<boost::system::error_code>* a,
                              boost::system::error_code b) 
{ 
    a->reset(b); 
}
void http_request::set_readsome_result(boost::optional<boost::system::error_code>* oa,
        boost::optional<std::size_t>* os, 
        boost::system::error_code a, std::size_t b)
{
    oa->reset(a);
    ob->reset(b);  
}

// Returns true if successful - false if a timeout occurs
template <typename MutableBufferSequence> 
bool read_with_timeout(boost::asio::ip::tcp::socket& sock, 
    const MutableBufferSequence& buffers, std::size_t& amount_read) 
{ 
    boost::optional<boost::system::error_code> timer_result; 
    boost::asio::deadline_timer timer(sock.io_service()); 
    timer.expires_from_now(seconds(1)); 
    timer.async_wait(boost::bind(set_result, &timer_result, _1)); 

    boost::optional<boost::system::error_code> read_error_result;
    boost::optional<std::size_t> read_size_result;
    sock.async_read_some(buffers, 
      boost::bind(set_result, &read_result, &read_size_result, _1, _2));

    sock.io_service().reset(); 
    while (sock.io_service().run_one()) 
    { 
        if (read_result) 
            timer.cancel(); 
        else if (timer_result) 
            sock.cancel(); 
    } 
    if (timer_result)
        return false;
    amount_read = *read_size_result;
    if (*read_error_result) 
        throw std::system_error(*read_result);
    return true;

}