views:

714

answers:

5

The software I'm working on needs to be able to connect to many servers in a short period of time, using TCP/IP. The software runs under Win32. If a server does not respond, I want to be able to quickly continue with the next server in the list.

Sometimes when a remote server does not respond, I get a connection timeout error after roughly 20 seconds. Often the timeout comes quicker.

My problem is that these 20 seconds hurts the performance of my software, and I would like my software to give up sooner (after say 5 seconds). I assume that the TCP/IP stack (?) in Windows automatically adjusts the timeout based on some parameters?

Is it sane to override this timeout in my application, and close the socket if I'm unable to connect within X seconds?

(It's probably irrelevant, but the app is built using C++ and uses I/O completion ports for asynchronous network communication)

+1  A: 

All configurable TCP/IP parameters for Windows are here

See TcpMaxConnectRetransmissions

Vinko Vrsalovic
If they don't mind overriding this globally for all other users and programs...
ephemient
+1  A: 

On Linux you can

int syncnt = 1;
int syncnt_sz = sizeof(syncnt);
setsockopt(sockfd, IPPROTO_TCP, TCP_SYNCNT, &syncnt, syncnt_sz);

to reduce (or increase) the number of SYN retries per connect per socket. Unfortunately, it's not portable to Windows.

As for your proposed solution: closing a socket while it is still in connecting state should be fine, and it's probably the easiest way. But since it sounds like you're already using asynchronous completions, can you simply try to open four connections at a time? If all four time out, at least it will only take 20 seconds instead of 80.

ephemient
+1  A: 

You might consider trying to open many connections at once (each with its own socket), and then work with the one that responds first. The others can be closed.

You could do this with non-blocking open calls, or with blocking calls and threads. Then the lag waiting for a connection to open shouldn't be any more than is minimally nessecary.

T.E.D.
You can also use blocking calls and select()
sbk
+1  A: 

You have to be careful when you override the socket timeout. If you are too aggressive and attempt to connect to many servers very quickly then the windows TCP/IP stack will assume your application is an internet worm and throttle it down. If this happens, then the performance of your application will become even worse.

The details of when exactly the throttling back occurs is not advertised, but the timeout you propose ( 5 seconds ) should be OK, in my experience.

The details that are available about this can be found here

ravenspoint
The throtling of TCP connects is a client OS only feature (XP, Vista). A server product (Windows 2003, Windows 2008) has no throtling.
Remus Rusanu
It seems likely that the questioner, and the vast majority of readers, is using XP or Vista.
ravenspoint
+4  A: 

If you use IO completion ports and async operations, why do you need to wait for a connect to complete before continuing with the next server on the list? Use ConnectEx and pass in an overlapped structure. This way the individual server connect time will no add up, the total connect time is the max server connect time not the sum.

Remus Rusanu
So you're suggesting that I connect to a lot of extenal servers as once? But when I've connected, I'll have to send data to these servers. I have to perform a range of activities, such as local file access and calculations among other things. If I connect to 100 different servers, and they all respond directly, I'll have to do the local calculations in 100 parallell threads, or, I have to be slow in which case they'll probably disconnect me for taking too long time. The local stuff doesn't scale this way. So to me, your suggestion sounds like a bad idea.
Nitramk
http://en.wikipedia.org/wiki/Deus_ex_machina
Remus Rusanu