在TCP连接尝试后,如何使Windows荣获ICMP连接拒绝消息

我们有一个工具,用于通过TCP远程pipe理服务器进程。 其中一个工具function是通过在指定的时间段内尝试连接到服务器,来检查服务器是否正在运行。

当我们使用这个工具来检查一个服务器没有运行的时候,我们注意到在Windows上时间的准确性是相当的差,比如尝试连接2s到一个死的服务器会导致工具运行7s,而不是预期的2s而在Linux上,计时精确到几毫秒。 这里的问题是,我们在启动脚本中使用该工具,将服务器声明为死的延迟增加了启动脚本的运行时间。

事实certificate,罪魁祸首似乎是Windows TCP / IP协议栈:一个失败的连接到Windows上的本地端口的尝试取决于机器需要2-5秒才能完成,而在Linux上几乎是瞬间的。 理论上,Windows堆栈对服务器返回的ICMP连接拒绝消息不重视/不感兴趣,并继续进行另一次连接尝试。

因此,我的问题包括两个部分:i)上述理论看起来是否合理?ii)如何告诉Windows遵守ICMP响应?

– 劳里

有人回答说,从服务器的实际响应是一个TCP RST而不是一个ICMP消息,但那个答案从那时起被删除。

无论如何,我做了一些更多的挖掘,并看到一些Wireshark的连接尝试失败的痕迹:

i)响应实际上是TCP RST,ACK,而不是我原先认为的ICMP消息

ii)Windows TCP / IP堆栈被实现为在RST之后重试连接尝试,ACK希望服务器可能在连接超时内奇迹般地重新出现[1]

iii)pipe理员可以将HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters中的TcpMaxConnectRetransmissionsregistry项设置为比默认值3(WinNT)或2(Win2k)更低的值。

所以,答案是调整registry,并降低TcpMaxConnectRetransmissions为0或1.我唯一的问题是这个“解决scheme”是AFAICT这也会影响连接尝试,其中最初的SYN被丢弃在networking中,在这种情况下,将值设置为0是一个坏主意,并将其设置为1仍然会导致我的脚本超过必要的运行时间。

[1]欲了解更多信息: http : //support.microsoft.com/kb/175523

– 劳里