我正在开发一个监听端口 3000 的应用程序。显然有一个实例仍在监听该端口,因为每当我启动它时,它都无法创建监听器(C#、TcpListener,但这无关紧要),因为该端口已被占用。
现在,该应用程序在任务管理器中不存在,因此我尝试找到它的 PID 并将其终止,这导致了这个有趣的结果:
C:\Users\username>netstat -o -n -a | findstr 0.0:3000
TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 3116
C:\Users\username>taskkill /F /PID 3116
ERROR: The process "3116" not found.
我之前从未见过这种行为,并且认为这很有趣,看看是否有人有解决方案。
更新:我启动了 Process Explorer 并搜索了 3000,发现了以下内容:
<Non-existent Process>(3000): 5552
我右键单击它并选择“关闭句柄”。它不再出现在 Process Explorer 中,但仍显示在 netstat 中,并且仍阻止应用程序启动侦听器。
更新 2:已找到Windows 版 TCPView它将进程显示为"<non-existent>"
。与 CurrPorts 一样,当我尝试在此工具中关闭连接时,什么也没有发生。
答案1
为了避免在套接字上无休止地等待,你的程序应该使用setsockopt 函数使用 SO_REUSEADDR 和 SO_RCVTIMEO 参数:
SO_REUSEADDR : Allows the socket to be bound to an address that is already in use.
SO_RCVTIMEO : Sets the timeout, in milliseconds, for blocking receive calls.
答案2
我们也遇到了同样的问题,并使用进程探索器从 Microsoft Sysinternals 查找不再存在的进程 ID。
事实证明,该进程被多个 DrWatson 进程引用。终止这些进程可释放端口。DrWatson 用于向 Microsoft 发送内存转储,这需要几个小时,因为崩溃的进程当时占用了几十 GB 的内存。
答案3
我认为你应该给当前端口尝试
CurrPorts 是一款网络监控软件,可显示本地计算机上当前打开的所有 TCP/IP 和 UDP 端口的列表。对于列表中的每个端口,还会显示有关打开该端口的进程的信息,包括进程名称、进程的完整路径、进程的版本信息(产品名称、文件说明等)、进程的创建时间以及创建该进程的用户。
此外,CurrPorts 允许您关闭不需要的 TCP 连接,终止打开端口的进程,并将 TCP/UDP 端口信息保存到 HTML 文件、XML 文件或制表符分隔的文本文件。
CurrPorts 还会自动用粉红色标记未识别应用程序(没有版本信息和图标的应用程序)拥有的可疑 TCP/UDP 端口
答案4
看到类似的问题,当根本原因是某个子进程继承了端口,父进程崩溃,而子进程仍然持有端口时。解决方法是找出仍在运行的子进程并停止它。在此示例中,不存在的进程 PID 为 7336
> wmic process get processid,parentprocessid | findstr/i 7336
7336 23828
要停止该过程:
> taskkill /f /pid 23828
这解决了这个问题。