应用程序崩溃后仍然在监听套接字

时间:2010-12-16 20:32:02

标签: c++ sockets windows-server-2008-r2

我在Windows 2008x64上遇到了我的一个C ++应用程序的问题(同样的应用程序在Windows 2003x64上运行得很好)。

崩溃后甚至有时在常规关机/重启周期后,在端口82上使用套接字时遇到问题需要接收命令。

查看netstat我看到套接字在应用程序停止后超过10分钟仍然处于侦听状态(该进程肯定不再运行)。

  TCP    0.0.0.0:82             LISTENING

我尝试将套接字选项设置为REUSEADDR但据我所知只会影响重新连接到处于TIME_WAIT状态的端口。无论哪种方式,这种变化似乎没有任何区别。

int doReuse = 1;
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR,
           (const char *)&doReuse, sizeof(doReuse)); 

我能做些什么来解决或至少避免这个问题?

修改

netstat -an,但这就是我得到的所有内容:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING

对于netstat -anb,我得到:

  TCP    0.0.0.0:82             0.0.0.0:0              LISTENING
 [System]

我知道正常关闭,但即使应用程序由于某种原因崩溃,我仍然需要能够重新启动它。有问题的应用程序使用内部使用Windows套接字API的内部库。

修改

显然没有解决这个问题的方法,所以对于开发我将使用代理/工具来解决它。感谢所有的建议,非常感谢。

6 个答案:

答案 0 :(得分:2)

如果这只会在调试时受到伤害,请使用sysinternals人员中的tcpview强制关闭套接字。我假设它适用于您的平台,但我不确定。

如果您正在对任何套接字执行阻止操作,请不要使用无限期超时。根据我的经验,这可能会在多处理器计算机上造成奇怪的行为。我不确定它是什么Windows服务器操作系统,但它是2003 Server之前的一个或两个版本。 而不是无限期超时,使用30到60秒的超时,然后重复等待。如果你正在使用它们,这也适用于重叠的IO和IOCompletion端口。

如果这是一款适合其他人使用的应用,祝您好运。使用套接字时,Windows可能是一个纯粹的混蛋......

答案 1 :(得分:1)

  

我尝试将套接字选项设置为   REUSEADDR但据我所知   仅影响重新连接到端口   那是在TIME_WAIT状态。

这不太正确。它可以让你重新使用TIME_WAIT状态的端口用于任何目的,即监听或连接。但我同意这对此没有帮助。关于操作系统需要花费10分钟来检测失败的听众的评论我感到很惊讶。它应该在进程结束时立即清除所有资源,而不是处于TIME_WAIT状态的端口。

答案 2 :(得分:0)

首先要检查的是,确实是您的应用程序正在侦听该端口。使用:

netstat -anb

确定哪个进程正在该端口上进行侦听。

要检查的第二件事是,当您的应用程序关闭时,您正在正常关闭套接字。如果您使用的高级套接字API不应该是一个问题( 使用套接字API,对吗?)。

最后,您的应用程序是如何构建的?有线程吗?它是否启动了其他流程?你怎么知道你的应用程序真的关闭了?

答案 3 :(得分:0)

运行

netstat -ano

这将为您提供打开端口的进程的PID。从任务管理器检查该过程。确保选中“所有用户的列表进程”。

答案 4 :(得分:0)

http://hea-www.harvard.edu/~fine/Tech/addrinuse.html是" Bind:已经在使用的地址"错误。

一些摘录:

  

TIME_WAIT是在进程完成后通常将端口占用几分钟的状态。相关超时的长度因操作系统而异,在某些操作系统上可能是动态的,但典型值在1到4分钟范围内。

     

避免策略

     

<强> SO_REUSEADDR

     

这是减少已经使用的&#34;地址的最简单和最有效的选择&#34;错误。

     

客户首先关闭

     如果远程端启动关闭,则可以避免TIME_WAIT。因此,服务器可以通过让客户端先关闭来避免问题。

     

减少超时

     

如果(无论出于何种原因)这些选项都不适合您,也可以缩短与TIME_WAIT相关的超时。

答案 5 :(得分:0)

看到https://superuser.com/a/453827/56937后,我发现有一个WerFault进程被暂停。

它必须从不存在的进程继承套接字,因为查杀它会释放我的侦听端口。