windows 我应该实现自己的 TCP/IP 套接字超时吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1568419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:17:32  来源:igfitidea点击:

Should I implement my own TCP/IP socket timeouts?

c++windowssocketstcptimeout

提问by Nitramk

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.

我正在开发的软件需要能够在短时间内使用 TCP/IP 连接到许多服务器。该软件在Win32下运行。如果服务器没有响应,我希望能够快速继续列表中的下一个服务器。

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

有时当远程服务器没有响应时,我会在大约 20 秒后收到连接超时错误。通常超时来得更快。

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?

我的问题是这 20 秒会损害我的软件的性能,我希望我的软件早点放弃(比如 5 秒后)。我假设 Windows 中的 TCP/IP 堆栈(?)会根据某些参数自动调整超时?

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

在我的应用程序中覆盖此超时并在 X 秒内无法连接时关闭套接字是否合理?

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

(这可能无关紧要,但该应用程序是使用 C++ 构建的,并使用 I/O 完成端口进行异步网络通信)

采纳答案by ephemient

On Linux you can

在 Linux 上你可以

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.

减少(或增加)每个套接字每个连接的 SYN 重试次数。不幸的是,它不能移植到 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.

至于您提出的解决方案:在套接字仍处于连接状态时关闭它应该没问题,这可能是最简单的方法。但是既然听起来您已经在使用异步完成,您可以尝试一次打开四个连接吗?如果四个都超时,至少只需要20秒而不是80秒。

回答by Remus Rusanu

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 ConnectExand 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.

如果使用 IO 完成端口和异步操作,为什么在继续列表中的下一个服务器之前需要等待连接完成?使用ConnectEx并传入重叠结构。这样单个服务器的连接时间不会相加,总连接时间是最大服务器连接时间而不是总和。

回答by T.E.D.

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.

您可以使用非阻塞打开调用或阻塞调用和线程来执行此操作。然后等待连接打开的延迟不应超过最低限度的必要性。

回答by ravenspoint

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.

覆盖套接字超时时必须小心。如果您过于激进并试图非常快速地连接到许多服务器,那么 Windows TCP/IP 堆栈将假定您的应用程序是 Internet 蠕虫并对其进行限制。如果发生这种情况,那么您的应用程序的性能将变得更糟。

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.

没有公布具体何时发生节流的详细信息,但根据我的经验,您建议的超时(5 秒)应该没问题。

The details that are available about this can be found here

可以在此处找到有关此的详细信息

回答by Vinko Vrsalovic

All configurable TCP/IP parameters for Windows are here

Windows 的所有可配置 TCP/IP 参数都在这里

See TcpMaxConnectRetransmissions

请参见 TcpMaxConnectRetransmissions