6

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?

Community
  • 1
  • 1
Roby
  • 2,011
  • 4
  • 28
  • 55
  • Read [how to set a timeout on blocking socket](http://stackoverflow.com/questions/291871/how-to-set-a-timeout-on-blocking-sockets-in-boost-asio) It seems that there is not easy way. – O.C. May 18 '11 at 07:56

2 Answers2

13

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.

Carlo Medas
  • 803
  • 9
  • 15
  • 1
    Isn't there some library I must include to make this work? – Tomáš Zato Mar 16 '13 at 15:57
  • gives error: ‘HttpClientImpl’ has not been declared – Stefan Rogin Mar 13 '14 at 07:16
  • Can you please help me to find why your answer [does not work](http://stackoverflow.com/questions/33668717/boost-asio-blocking-mode-timeout-on-native-socket-handle-is-not-working) for me? – VP. Nov 12 '15 at 10:37
  • Setting the socket options may not have the desired affects on the Asio operations. See [here](http://stackoverflow.com/a/30428941/1053968) for details. – Tanner Sansbury Nov 12 '15 at 17:22
  • 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? – Anonymous Dec 01 '15 at 10:10
5

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.

Chad
  • 18,706
  • 4
  • 46
  • 63
  • 1
    +1 for recommending async calls. – Sam Miller May 19 '11 at 03:04
  • 1
    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. – wallyk May 19 '11 at 03:42
  • 5
    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. – Chad May 19 '11 at 18:28
  • @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. – Sam Miller May 21 '11 at 00:30
  • @Chad What a pity is that `deadline_timer` is not avialble when I use the standalone [`asio`](https://think-async.com/Asio/) which doesn't depent on `Boost`. Any idea about how to accomplish this goal with standalone `asio`? – John Sep 16 '21 at 02:10
  • The documentation for non-boost have both deadline_timer and steady_timer listed? https://think-async.com/Asio/asio-1.18.2/doc/asio/reference.html – Chad Sep 16 '21 at 02:46