boost::asio, synchronous read with timeout

The boost::asio (which means asynchronous input/output) library, is quite powerful library for asynchronous i/o, but it could be a bit difficult at first to figure out how to do a normal synchronous read. So, as a reminder for my future-me, and for you, this snippet it’ll be very useful to accomplish that. Probably there will be another ways for doing that, but this is how I managed to do it:

using namespace boost::asio;
using namespace boost::system;
using boost::optional;
ip::tcp::socket _socket; // it could be another kind of socket, not only ip::tcp
 * Dumb function to be used as handler argument and save the error_code
 * into a pointer
 * e.g.: boost::bind( &set_result, some_pointer, _1 )
void set_result( optional<error_code>* a, error_code b ) 
  a->reset( b );
#define TIMEOUT 60
 * it uses _socket 
 * if timeout happends throw a system_error exception
template<typename MutableBufferSequence>
optional<error_code> read_with_timeout(
    const MutableBufferSequence& buffer
  ) throw( system_error )
  optional<error_code> timer_result;
  optional<error_code> read_result;
  deadline_timer timer( _socket.io_service() );
  timer.expires_from_now( seconds(TIMEOUT) );
  timer.async_wait( boost::bind(&set_result, &timer_result, _1) );
      boost::asio::transfer_at_least( buffer_size_helper(buffer) ),
      boost::bind( &set_result, &read_result, _1 )
  while ( _socket.io_service().run_one() )
    if ( read_result )
    else if ( timer_result )
      throw system_error(
          error_code( errc::timed_out, get_generic_category() )            
  return read_result;

I hope it will be useful, have fun.

One Thought on “boost::asio, synchronous read with timeout

  1. Pingback: Writing a Thread-Per-Connection Server in Boost C++ « newspaint

Post Navigation