如何杀死一个已死但正在监听的进程?

Sre*_*kel 53 windows tcp kill process netstat

我正在开发一个侦听端口 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.
Run Code Online (Sandbox Code Playgroud)

我以前从未见过这种行为,并认为看看是否有人有解决方案很有趣。

更新:我启动了 Process Explorer 并搜索了 3000 并找到了这个:

<Non-existent Process>(3000): 5552
Run Code Online (Sandbox Code Playgroud)

我右键单击它并选择“关闭句柄”。它不再在 Process Explorer 中,但仍显示在 netstat 中,并且仍会阻止应用程序启动侦听器。

更新 2:找到了 Windows 的 TCPView,它将进程显示为"<non-existent>". 与 CurrPorts 一样,当我尝试关闭此工具中的连接时没有任何反应。

har*_*ymc 14

为了避免在套接字上无休止的等待,您的程序应该使用带有 SO_REUSEADDR 和 SO_RCVTIMEO 参数的setsockopt 函数

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. 
Run Code Online (Sandbox Code Playgroud)


小智 12

我们遇到了同样的问题,并使用Microsoft Sysinternals 的Process Explorer查找不再存在的进程 ID。

事实证明,该流程被多个 DrWatson 流程引用。杀死这些进程释放​​了端口。DrWatson 用于向 Microsoft 发送内存转储,这需要几个小时,因为当时崩溃的进程拥有数十 GB 的内存。


Nic*_*ate 8

可能的问题是您的进程已经启动了另一个继承了套接字句柄的(子)进程,并且它仍在运行。

有多种方法可以防止这种情况发生,例如:ProcessStartInfo.UseShellExecute = true;


Sat*_*hat 7

我认为你应该试试CurrPorts

CurrPorts 是网络监控软件,可显示本地计算机上所有当前打开的 TCP/IP 和 UDP 端口的列表。对于列表中的每个端口,还会显示打开该端口的进程的信息,包括进程名称、进程的完整路径、进程的版本信息(产品名称、文件描述等)、打开端口的时间进程已创建,以及创建它的用户。

此外,CurrPorts 允许您关闭不需要的 TCP 连接,终止打开端口的进程,并将 TCP/UDP 端口信息保存到 HTML 文件、XML 文件或以制表符分隔的文本文件中。

CurrPorts 还会自动用粉红色标记未知应用程序拥有的可疑 TCP/UDP 端口(没有版本信息和图标的应用程序)

替代文字

  • 它显示在进程名称“系统”下的列表中。我尝试右键单击该项目以强制关闭端口,但没有任何反应。 (4认同)

小智 5

当根本原因是创建继承端口的某些子进程时,看到类似的问题,父进程崩溃,而子进程仍保留端口。解决方案是识别仍在运行的子进程并将其停止。在此示例中,不存在的进程 PID 为 7336

> wmic process get processid,parentprocessid | findstr/i 7336
7336             23828
Run Code Online (Sandbox Code Playgroud)

要停止此过程:

> taskkill /f /pid 23828
Run Code Online (Sandbox Code Playgroud)

这解决了问题。


小智 5

我已经尝试了上面评论的所有解决方案,但没有一个对我有用。我一直在研究,我得到了这个答案,这是使用@Michael 评论和此链接https://serverfault.com/questions/181015/how-do-you-free-up-a-port-being- 的组合死进程保持打开

  1. 首先,您必须使用端口号找到导致问题的进程:

    netstat -abno | findstr /i "listening"| find ":3000"
        TCP    0.0.0.0:3000           0.0.0.0:0              LISTENING       3116
    
    Run Code Online (Sandbox Code Playgroud)
  2. 其次,您必须使用@Michael 中的代码找到父进程 ID (ppid)

    wmic process get processid,parentprocessid | findstr/i 3116
        3116             23828
    
    Run Code Online (Sandbox Code Playgroud)
  3. 接下来,您必须使用下一个代码找到子进程 ID

    wmic process where (ParentProcessId=23828) get Caption,ProcessId
        Caption        ProcessId
        wireguard.exe  27400
    
    Run Code Online (Sandbox Code Playgroud)
  4. 杀死从子进程到父进程的所有进程

    taskkill /f /pid 27400 
    taskkill /f /pid 3116 
    taskkill /f /pid 23828
    
    Run Code Online (Sandbox Code Playgroud)

那为我解决了这个问题。


小智 1

您可以在Process Explorer中看到该流程吗?如果是,那么您可以从那里杀死它,但只有在您调查它实际上是什么之后(您可以看到加载到进程中的所有 dll)