boost asio timeout

13,678

Solution 1

Fist of all I believe that you should ALWAYS use the async methods since they are better and your design will only benefit from a reactor pattern approach. In the bad case that you're in a hurry and you're kind of prototyping, the sync methods can be useful. In this case I do agree with you that without any timeout support, they cannot be used in the real world.

What I did was very simple:

void HttpClientImpl::configureSocketTimeouts(boost::asio::ip::tcp::socket& socket)
{
#if defined OS_WINDOWS
    int32_t timeout = 15000;
    setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
    setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout));
#else
    struct timeval tv;
    tv.tv_sec  = 15; 
    tv.tv_usec = 0;         
    setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
#endif
}

The code above works both on windows and on Linux and on MAC OS, according to the OS_WINDOWS macro.

Solution 2

Using boost::asio and the sychronous calls like read_until do not allow for easily setting a timeout.

I'd suggest moving to asynchronous calls (like async_read), and combining that with a deadline_timer to accomplish this goal.

Share:
13,678
Roby
Author by

Roby

Updated on June 24, 2022

Comments

  • Roby
    Roby almost 2 years

    Possible Duplicate:
    How to set a timeout on blocking sockets in boost asio?

    I read some of the entries before about the timeout but I don't understand.

    I want a defined timeout for the connection. the connect code looks like:

    try{
      boost::asio::ip::tcp::resolver              resolver(m_ioService);
      boost::asio::ip::tcp::resolver::query       query(link.get_host(), link.get_scheme());
      boost::asio::ip::tcp::resolver::iterator    endpoint_iterator = resolver.resolve(query);
      boost::asio::ip::tcp::resolver::iterator    end;
      boost::system::error_code                   error   =   boost::asio::error::host_not_found;
    
      while (error && endpoint_iterator != end)
       {
        m_socket.close();
        m_socket.connect(*endpoint_iterator++, error);
       }
    }
    

    also I want a read timeout.

    I use boost::asio::read_until(m_socket, response, "\r\n"); for read the header.

    is it possible to set SIMPLE a timeout?

  • Sam Miller
    Sam Miller almost 13 years
    +1 for recommending async calls.
  • wallyk
    wallyk almost 13 years
    Good luck with async asio. I had mysterious crashes using them, not often, but enough to doubt the application's stability. They all went away when I switched to multiple threads each with synchronous asio.
  • Chad
    Chad almost 13 years
    Sorry that you've had problems with boost::asio. While it's definitely a learning curve and there are a lot of things that have to be done "just right", I've found that for cross-platform development of applications under heavy network load (to the point that synchronous calls like select(), were causing major bottlenecks), boost::asio has performed extremely well and given definite benefits.
  • Sam Miller
    Sam Miller almost 13 years
    @wally async programming is hard to get correct, nobody will deny that. The inversion of the application's flow control is particularly confusing at times.
  • Tomáš Zato
    Tomáš Zato about 11 years
    Isn't there some library I must include to make this work?
  • Stefan Rogin
    Stefan Rogin about 10 years
    gives error: ‘HttpClientImpl’ has not been declared
  • Victor Polevoy
    Victor Polevoy over 8 years
    Can you please help me to find why your answer does not work for me?
  • Tanner Sansbury
    Tanner Sansbury over 8 years
    Setting the socket options may not have the desired affects on the Asio operations. See here for details.
  • Anonymous
    Anonymous over 8 years
    Has someone actually got a timeout implemented with the code above using Linux? When using windows everything works fine. However, when I compile and run this with Ubuntu, both setsockop calls do not return an error code but the read-calls are still blocking?
  • John
    John over 2 years
    @Chad What a pity is that deadline_timer is not avialble when I use the standalone asio which doesn't depent on Boost. Any idea about how to accomplish this goal with standalone asio?
  • Chad
    Chad over 2 years
    The documentation for non-boost have both deadline_timer and steady_timer listed? think-async.com/Asio/asio-1.18.2/doc/asio/reference.html