开发者

Should I implement my own TCP/IP socket timeouts?

开发者 https://www.devze.com 2022-12-09 01:23 出处:网络
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 quic

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 i开发者_高级运维s built using C++ and uses I/O completion ports for asynchronous network communication)


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.


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.


All configurable TCP/IP parameters for Windows are here

See TcpMaxConnectRetransmissions


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号