TCP/IP堆栈是否可以通过编程方式终止?

3
我们的服务器应用程序正在监听一个端口,一段时间后不再接受传入连接。(虽然我很想解决这个问题,但这不是我在这里要问的问题;))
奇怪的是,当我们的应用程序停止在端口44044上接受连接时,IIS(在端口8080上)也会停止响应。杀死我们的应用程序可以解决所有问题 - IIS开始再次响应。
所以问题是,一个应用程序能否破坏整个TCP/IP协议栈?或者说,一个应用程序如何做到这一点?
无意义的细节:我们的应用程序使用C#编写,在XP/SP2上使用.Net 2.0。
澄清:IIS没有“拒绝”尝试的连接。它从未看到过它们。客户端收到“服务器未能及时响应”的消息(使用.Net TCP客户端)。

相反的解决方法如何?如果你关闭IIS,你的应用程序是否开始接受连接并响应流量? - benc
7个回答

5

你可能会饿死堆栈。在高开/关事务每秒环境下,例如为许多未汇集请求提供服务的web服务器,很容易耗尽堆栈。

默认的TIME-WAIT延迟时间加剧了这个问题 - 在被回收之前必须关闭套接字的时间量默认为90秒(如果我没记错的话)

有一堆可以调整的注册表键 - 建议至少创建/编辑以下键

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

TcpTimedWaitDelay = 30
MaxUserPort = 65534 
MaxHashTableSize = 65536 
MaxFreeTcbs = 16000 

在MSDN和Technet上有大量关于这些键的功能的文档。


这个解决方案在一段时间内可以帮助我们避免遇到问题。但即使有了这个修复,我们最终还是会停滞不前。感谢你的帮助。 - Gene

4
你是否已经超出了可用的端口句柄上限?
netstat -a
当一个应用程序打开和关闭端口(但实际上没有正确地关闭它们)时,我看到了类似的情况。

好的建议。我们一直在使用netstat和TCPView(http://technet.microsoft.com/en-us/sysinternals/bb897437.aspx)进行诊断,但是没有什么明显的问题。 - Gene
netstat 可能不是最好的工具,因为它没有提供关于连接创建的详细信息。 - benc

1
使用netstat -a命令查看发生问题时的活动连接。也许,您的服务器应用程序没有关闭/处理“已关闭”的连接。

1

大家提供了很好的建议,感谢你们的帮助。

这就是发生的情况: 事实证明我们有几个服务竞争同一个端口,大多数情况下,“正确”的服务将获取该端口。偶尔第二个服务会夺走端口,第一个服务将尝试打开另一个端口。从那时起,服务每次为请求提供服务时都会抓取新端口(因为它们未使用它们首选的端口),最终我们将耗尽所有可用端口。

当然,实际问题是:“应用程序是否可以搞乱整个TCP/IP协议栈?”,答案是:可以。一种方法是监听大量端口。


你遇到了无限监听器的问题?这应该会在 netstat -a 中显示,除非大量的监听器导致了堆栈级别的问题,从而实际上没有打开监听器。 - benc

0
从支持和系统管理员的角度来看,我只在极少数情况下(不止一次)见过这种情况,但它肯定会发生。
当你诊断问题时,你应该仔细消除可能的原因,而不是在出现问题的第一个迹象时盲目地重新启动系统。我之所以这样说,是因为我与许多客户合作时,他们往往会这样做。

0

我猜RichS提到的端口号评论是正确的。

除此之外,TCP/IP协议栈只是操作系统中的一个模块,因此可能存在漏洞,使得应用程序可以将其关闭。这不会是第一个被程序杀死的驱动程序。

(向Andrew Tanenbaum致敬,他坚持认为操作系统应该是模块化而不是单片式的。)


0
我自己也遇到过几个类似的情况。一个好的故障排除步骤是尝试从受影响的机器连接到一个已知良好的目标,该目标此时没有任何连接问题。如果连接尝试失败,则很可能会在错误消息/代码中获得更有趣的细节。例如,它可能会说没有足够的句柄或内存。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接