可以通过编程方式杀死TCP / IP堆栈吗?
我们的服务器应用程序正在侦听端口,并且一段时间后,它不再接受传入的连接。 (尽管我很想解决这个问题,但这不是我要问的;)
奇怪的是,当我们的应用停止在端口44044上接受连接时,IIS(在端口8080上)也不再接受连接。终止我们的应用程序可以修复IIS重新开始响应的所有问题。
因此,问题是,应用程序可以将整个TCP / IP堆栈弄乱吗?也许,应用程序如何做到这一点?
毫无意义的细节:我们的应用程序是在XP / SP2上以.Net 2.0下的C#编写的。
说明:IIS不会"拒绝"尝试的连接。从来没有见过他们。客户端收到"服务器未及时响应"消息(使用.Net TCP客户端。)
解决方案
我们还没有最大化可用的端口句柄吗?netstat -a
当应用打开和关闭端口(但实际上没有正确关闭端口)时,我看到了类似的内容。
发生这种情况时,请使用netstat -a查看活动连接。也许,服务器应用程序没有关闭/处置"关闭"的连接。
我想RichS的端口号注释是正确的。
除此之外,TCP / IP堆栈只是操作系统中的一个模块,因此可能会存在一些错误,这些错误可能会使应用程序将其杀死。它不会是第一个被程序杀死的驱动程序。
(向安德鲁·塔南鲍姆(Andrew Tanenbaum)致敬的是,他坚持认为操作系统应该是模块化的,而不是整体的。)
我们可能会饿死堆栈。在每秒高开/关交易的环境中消耗掉非常容易,例如网络服务器处理大量未池化的请求。
默认的TIME-WAIT延迟可以消除套接字在被回收之前必须关闭的时间,默认为90秒(如果我记得没错)
有很多可以调整的注册表项,建议至少创建/编辑以下注册表项
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters TcpTimedWaitDelay = 30 MaxUserPort = 65534 MaxHashTableSize = 65536 MaxFreeTcbs = 16000
MSDN和Technet上的大量文档介绍了这些键的功能。
我本人也经历过两次类似的情况。一个好的故障排除步骤是尝试从受影响的计算机到知名目的地的连接,该连接当时未遇到任何连接问题。如果连接尝试失败,我们很可能会在错误消息/代码中获得更多有趣的详细信息。例如,它可以说没有足够的句柄或者内存。
每个人的好建议,感谢帮助。
所以这是怎么回事:
事实证明,我们有多个服务争用同一端口,大多数情况下,"适当的"服务会获得该端口。有时,第二个服务会抢走该端口,而第一个服务会尝试打开另一个端口。从那时起,服务将在每次服务请求时继续捕获新端口(因为它们未使用其首选端口),最终我们将耗尽所有可用端口。
当然,实际的问题是:"应用程序可以将整个TCP / IP堆栈弄乱吗?",对该问题的答案是:是的。一种方法是侦听大量端口。
从支持和系统管理员的角度来看,我仅在极少数情况下(不止一次)看到过这种情况,但是肯定会发生。
诊断问题时,应仔细排除可能的原因,而不是在出现故障时先盲目地重新启动系统。我之所以这么说是因为与我合作的许多客户都愿意这样做。