9

I have done a bit of searching and can't seem to find the answer I'm looking for, the only answers I could find were to use select to see if the socket had timed out which is what I am already doing.

What I want to know is there anyway to change the length of time before connect() would timeout? I am currently using select() which returns with errno set to EINPROGRESS until eventually returning with ETIMEDOUT. Is there anyway I can change the amount of time it takes before this ETIMEDOUT would occur? Currently it happens after about 60 seconds. I have tried adjusting the timeout value I pass into the select() call however, this only affects how long it takes before select() will time out.

ctor
  • 5,938
  • 2
  • 26
  • 37

2 Answers2

4
  1. Create the socket.
  2. Put it into non-blocking mode.
  3. Issue connect().
  4. Call select() or poll() or epoll(), specifying your desired timeout, and specifying the socket as a writefd, i.e. blocking until the timeout expires or the socket becomes writable.
  5. If the timeout expires, close the socket etc.
  6. Otherwise get the last error on the socket via getsockopt() and see if it's zero. If so, the connection has succeeded, otherwise it has failed.

Note that you cannot increase the connect timeout beyond the platform default (about a minute) by this means, but you can decrease it.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • This is what I'm already doing as I mentioned. My question was how do I extend the length of time before the timeout. The timeout specified in select does nothing but determine how long it takes before select() returns if nothing happens. – ctor Jun 17 '13 at 11:23
  • As I said, you can't extend the timeout beyond the platform default. And there's no point. A connect will succeed in a couple of seconds, if it's going to succeed at all. – user207421 Jun 17 '13 at 11:52
1

setsockopt(3) allows you to set this: http://linux.die.net/man/3/setsockopt

Slightly confusing, the timeout values are actually properties of the socket.

The options you are looking for are: SO_SNDTIMEO and SO_RCVTIMEO

EDIT As stated in the comments, this doesn't work for connect. Here is why: http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout As a solution it is suggested to set limits on the amount of retry SYN packets the kernel sends to establish the connection after the initial handshake failed. The time is doubled since the last retry, which means a) you can only set the amount of retries, which indirectly adds up to a connect timeout value and b) this is OS specific and system wide. Not a solution for you probably....

  • Unfortunately, this doesn't work for me. My socket is still timing out after 60 seconds or so even after setting both the properties you mentioned to 120 seconds. I did also notice that the man page you linked for `setsockopt` mentions that both of these are set to 0 by default and would therefore never time out. – ctor Jun 17 '13 at 09:59
  • You are right. There's a comment on that one: http://stackoverflow.com/questions/4181784/how-to-set-socket-timeout-in-c-when-making-multiple-connections where Roberto mentions they cannot be set at all. Looks like the options I mentioned are only for after the connection is established. Sorry. I guess it's up to the lower layers then. –  Jun 17 '13 at 10:02
  • Seems a bit silly if you ask me. It appears everyone who suggests the use of select doesn't even realise that the timeout passed to select doesn't affect the timeout of the actual socket connection but rather the timeout of the call to `select()` itself. Surely there's a simple way of specifying that you want don't want `connect()` to timeout for x length of time. – ctor Jun 17 '13 at 10:10
  • @nos, so there really is no way of increasing the timeout for `connect()`? – ctor Jun 17 '13 at 10:10
  • Neither of these options affects the connect timeout, and I don't see what's 'confusing' about these being 'properties of the socket'. What else are they going to be properties of? -1 – user207421 Jun 17 '13 at 10:19
  • I've long ago given up with OS-controlled connect timeouts. I put the socket objects onto a delta queue and time them out 'manually' using a thread waiting on the queue with a configuable timed wait(ms till timeout time of object at head of queue). It's the only method that always works. – Martin James Jun 17 '13 at 10:27
  • @MartinJames, how would that work with the `connect()` call timing out? If the latency on the network is the issue then surely if 60 seconds isn't long enough for the three way handshake to happen then that's going to be the case no matter how many times you call `connect()`. Unless by some random chance the latency drops dramatically, which in my case doesn't happen as I've left it running over the weekend in an attempt to see if it gets a connection, which it doesn't. – ctor Jun 17 '13 at 10:33
  • @nos They could be 'protocol properties' via what API? and if so why provide the *socket* in the function call? There *is* 'an API to set the TCP timers per socket', and this is it, but it only works for read and write. – user207421 Jun 17 '13 at 10:37
  • I've seen people doing this by interfacing with the kernel in /proc. As far as I know you can modify general TCP/IP parameters such as this one there. But that won't be portable in any way and should probably not be done. –  Jun 17 '13 at 10:38
  • @nos - yeah - even the slowest modem I have ever used got a connect up in less than 60 secs. If the standard timeout actually times out, it's usually because I wrote the server :) – Martin James Jun 17 '13 at 11:24
  • @nos TCP_SYNCNT changes the setting for this socket, not globally. – user207421 Jun 17 '13 at 11:56
  • @EJP , Yes, precisely. You hardly ever want to change such settings globally -though there are sysctls for them. – nos Jun 17 '13 at 11:58
  • @nos So what exactly is your point? You can't advance a case where the setting affects a single socket as a case where 'they could be protocol properties', or an example of setting a global protocol property even though a single socket is specified in the function call. It remains obscure why this poster found it 'slightly confusing' that SO_RCVTIMEO and friends are 'properties of the socket' when that's how they are documented, and when the function syntax makes that clear anyway. – user207421 Jun 17 '13 at 12:23
  • @nos So in what way exactly are you disagreeing with my statement that there is nothing confusing here? It is a distinction without a difference to say that 'they could be protocol properties' instead of 'properties of the socket' when they only apply to that socket rather than being global. – user207421 Jun 17 '13 at 22:05
  • @user2471020 As a solution it is suggested to use select() actually. What you suggest may not even be implementable, and it certainly doesn't constitute setting a connect timeout. – user207421 Aug 25 '14 at 09:43