2

I am writing a linux Qt5/c++ app that tries to connect to a peer using a QTcpSocket. I call

tcpsocket->connectToHost(address,port,options)

When the peer is available it works great and connects immediately. However, when the peer is not available: The first time I call the above, the connect waits 1 minute before I receive a SocketTimeoutError (5). Then, every subsequent call to connect might wait a second before I receive a ConnectionRefusedError (0), or might wait a full minute (depending on the system tested).

Is there a setsockopt I can use to reduce the time waiting for initial connect?

I should point out that I already set some socket options in order to quickly notify me of a lost connection (see below). Hopefully these aren't causing the 1 minute initial connection error delay:

int enableKeepAlive = 1;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enableKeepAlive, sizeof(enableKeepAlive));
int maxIdle = 5; /* seconds */
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &maxIdle, sizeof(maxIdle));
int count = 3;  // send up to 3 keepalive packets out, then disconnect if no response
setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &count, sizeof(count));
int interval = 2;   // send a keepalive packet out every 2 seconds (after the 5 second idle period)
setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
TSG
  • 4,242
  • 9
  • 61
  • 121
  • I found one reference on google to setsockopt(socket_handle, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option)) but it won't compile as there is no OP_CONNECT_TIMEOUT (at least not in my headers) – TSG Sep 19 '14 at 15:32

1 Answers1

0

Rather than rely on setsockopt(), why don't you instead set your socket to non-blocking mode and perform an asynchronous connect(). You'd then block on select(), poll() or whatever event demultiplexing mechanism you are using, setting the timeout to whatever you desire. Once it becomes writable you know the connection is complete.

Void - Othman
  • 3,441
  • 18
  • 18
  • I already do a non blocking connecting, which results in a socketerror signal. (Using QT so no select or poll). I realize I could also run a separate timer to expire in a shorter amount of time, but I'm looking for a socket option. – TSG Sep 19 '14 at 17:36
  • @GenerationDSystems: It seems odd that you'd need to set a socket option to make a non-blocking connect timeout at all. From what I understand [`connectToHost()`](http://qt-project.org/doc/qt-5/qabstractsocket.html#connectToHost) should return immediately with no timeout, and emit the `connected()` signal once the connection has been established. I did find an [old post about a similar problem](http://www.qtcentre.org/threads/37051-QTcpSocket-connectToHost%28%29-is-blocking-the-GUI!) to your own that implied it may have been a system/driver problem. Does the problem occur on other platforms? – Void - Othman Sep 19 '14 at 21:12
  • I don't think you understand the question. I wish to set the maximum time the socket will attempt to connect before issuing an error signal. At the moment that is 1 minutes, I need it < 5 seconds – TSG Sep 20 '14 at 01:02
  • 1
    Ah okay, my mistake. AFAIK, there isn't a standard way to do that. What platform are you on? Here's one way to do it on Linux, for example: http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout – Void - Othman Sep 22 '14 at 17:12
  • See above "I am writing a linux Qt5/c++ app". So you are saying that it cannot be done on a per connection basis - it must affect the whole OS only? – TSG Sep 22 '14 at 20:42
  • @GenerationDSystems: It looks like you can set the number of `SYN` retransmits at a socket granularity through something like the non-portable `setsockopt(fd, IPPROTO_TCP, TCP_SYNCNT, &syn_cnt, sizeof(syn_cnt))` - see the [tcp(7)](http://linux.die.net/man/7/tcp) man page - but I don't think that would get your connect timeout to less than 5 seconds since setting the `TCP_SYNCNT` to 1, for example, would give you something like 36 seconds, AFAICT. I've never tried this before, and just learned about it myself. YMMV. – Void - Othman Sep 23 '14 at 20:01