我遇到了使用端口30015的c++服务的问题。它运行得很好,但有时它无法启动,因为端口30015被占用,绑定失败并出现错误WSAEADDRINUSE。
我运行netstat命令以了解端口状态
netstat -aon | findstr 30015输出:
TCP 0.0.0.0:30015 0.0.0.0侦听6740
我在任务管理器中检查了PID 6740,这个PID不是被进程占用的。
在网络中搜索之后,我使用TCPVIEW查看端口的状态。TCPView在侦听模式下显示端口,进程名称为“不存在”。
应用程序基本上是压缩的,用7za解压文件。应用程序在30015端口上侦听请求,然后创建子进程,并传递命令行来运行7za命令来压缩和解压缩文件。
在这里,子进程不使用套接字。服务器在主线程上运行,并侦听端口30015。此问题在服务器重新启动后出现。
在这里,子进程并不使用套接字。我需要让bInheritHandle = FALSE吗?
发布于 2014-09-16 16:47:48
真的吗?这一切听起来都很困惑。netstat不可能显示处于LISTEN状态的套接字,但是不可能没有进程--尤其是当它显示pid的时候!您之所以感到困惑,是因为当您在任务管理器中查看时,进程只是退出了。netstat中的所有TCP连接都与一个正在运行的进程相关联(除了像时间等待套接字这样的特殊情况)。因此,找出哪个进程打开了套接字。
其次,我认为您想说的是,使用bInheritHandles=TRUE作为CreateProcess的参数可以导致处理泄漏。只有你才有你的代码--为什么不看看你孩子的句柄,看看是否有漏洞呢?只有在严格遵守规则的情况下才能使用bInheritHandles=TRUE,在新手程序员手中只会导致错误。创建一个具有适当安全描述符的命名管道,将命令行上的名称传递给子管道,然后再连接回去,而不是使用过于粗粒度的句柄继承。
最后,为了确保您确实知道如何将侦听套接字与SO_REUSEADDR绑定,以防止与使用同一端口的主动套接字发生冲突?(SO_REUSEADDR仍然不允许在同一地址/端口组合上创建两个被动套接字,尽管它在Windows上有点问题。)
发布于 2014-09-16 17:59:04
是的,在Windows上可能会发生这种情况。如果您已经创建了一个从父进程继承句柄的子进程,那么它将包括处于LISTEN状态的TCP服务器套接字,即使该PID已死,该套接字也将始终被列为父PID所有。
当您派生的所有子进程都退出时,这些套接字将消失,从而导致其句柄上的引用计数达到零。
从安全的角度来看,您不应该使用进程间句柄继承,特别是在启动第三方应用程序时,除非您有充分的理由需要该功能。
https://stackoverflow.com/questions/25853570
复制相似问题