即使应用程序关闭,端口仍然占用

时间:2014-09-15 17:29:53

标签: windows sockets service tcp network-programming

我正面临使用端口30015的c ++服务的问题。它运行正常,但有时它无法启动,因为端口30015被占用并且绑定失败并出现错误WSAEADDRINUSE。

我运行netstat命令来了解端口状态

 netstat -aon | findstr 30015

输出:

TCP 0.0.0.0:30015 0.0.0.0 LISTENING 6740

我检查了任务管理器中的PID 6740,这个PID不是由进程占用的。

在网上搜索后,我使用TCPVIEW查看端口的状态。 TCPView在监听模式下显示端口,进程名称为“不存在”。

应用程序基本上使用7za压缩,解压缩文件。应用程序在30015端口上侦听请求,然后创建子进程并传递命令行以运行7za命令来压缩和解压缩文件。

这里子进程不使用套接字。服务器在主线程上运行并侦听端口30015.重新启动服务器后出现此问题。

这里子进程不使用套接字。我需要制作bInheritHandle = FALSE吗?

2 个答案:

答案 0 :(得分:0)

你确定吗?这听起来很混乱。 netstat无法在LISTEN状态下显示套接字,但是没有进程 - 特别是如果它显示了pid!您感到困惑,因为在您查看任务管理器时,该过程只会退出。 netstat中的所有TCP连接都与正在运行的进程相关联(除了像TIME-WAIT套接字这样的异常情况)。因此,找出哪个进程打开套接字。

其次,我认为您试图说使用bInheritHandles=TRUE作为CreateProcess的参数会导致处理泄漏。只有你有你的代码 - 为什么不看看你孩子的手柄,看看你是否有泄漏?它只能使用bInheritHandles=TRUE具有良好的纪律,在新手程序员手中它只会导致错误。使用合适的安全描述符创建一个命名管道,将命令行上的名称传递给子项,然后连接回来,而不是使用过于粗糙的句柄继承。

最后,为了确保您知道将侦听套接字绑定到SO_REUSEADDR以防止与使用相同端口的活动套接字冲突? (SO_REUSEADDR仍然不会在同一个地址/端口组合上创建两个被动套接字,尽管在Windows上有点破坏。)

答案 1 :(得分:0)

是的,这可能发生在Windows上。如果您创建了一个从父进程继承句柄的子进程,那么该进程包括处于LISTEN状态的TCP服务器套接字,即使该PID已经死亡,也将始终列为父PID所拥有的。

当您生成的所有子进程都退出时,这些套接字将消失,导致其句柄上的引用计数达到零。

从安全角度来看,您不应该使用进程间句柄继承,尤其是在启动第三方应用程序时,除非您有充分的理由需要该功能。