在Windows上查找使用端口的进程的PID

146

我的服务在启动时崩溃,并显示经典错误:

java.rmi.server.ExportException: Listen failed on port: 9999

我该如何找到杀死它的进程?


更复杂的替代方案在这里:https://dev59.com/nXVD5IYBdhLWcg3wOo5h - Thomas
可能是重复的问题:如何在Windows上找出哪个进程正在监听端口? - Ben Voigt
7个回答

275

只需打开命令行并输入以下命令(假设您的端口是123456):

netstat -a -n -o | find "123456"

你会看到你所需要的一切。

标题为:

 Proto  Local Address          Foreign Address        State           PID
 TCP    0.0.0.0:37             0.0.0.0:0              LISTENING       1111

1
这里我如何只获取PID,因为它返回了整个详细信息。 - Gobi M
1
如何从上述结果中获取唯一的PID - Chinya
21
或者,nestat -aon | findstr 123456。 该命令用于在Windows命令提示符中查找指定端口(此处为123456)的进程ID(PID)。 - ROMANIA_engineer
在Windows上实现这一点的简单方法在这个问题中展示 - https://dev59.com/nXVD5IYBdhLWcg3wOo5h - Dracontis
5
对于Windows/Cygwin系统,可能需要使用以下命令: netstat -a -n -o | grep "123456" 该命令用于查找特定端口(123456)的网络连接状态,并显示相关进程的PID。 - WebComer
2
为了更精确的结果,在端口号前加上冒号,找到“:123456”。 - billrichards

112

查找在Windows上使用指定端口(例如端口号为"9999")的进程PID

netstat -aon | find "9999"

-a 显示所有连接和监听端口。

-o 显示与每个连接关联的拥有进程ID。

-n 以数字形式显示地址和端口号。

输出:

TCP    0.0.0.0:9999       0.0.0.0:0       LISTENING       15776

然后通过进程ID杀死该进程

taskkill /F /PID 15776

/F - 指定强制终止进程。

注意:您可能需要额外的权限(以管理员身份运行)才能结束某些特定的进程。


为什么netstat不加n标志就无法退出? - Jared Beach
2
@JaredBeach - 它正在等待反向DNS名称解析,因此在超时完成后它最终会完成。如果这在内部IP上挂起,则表明您的本地DNS服务器存在问题。 - Steve Friedl

26

指令:

netstat -aon | findstr 4723

输出:

TCP    0.0.0.0:4723           0.0.0.0:0                LISTENING       10396
在 Windows 中使用 for 命令剪切进程 ID "10396"。

命令:

for /f "tokens=5" %a in ('netstat -aon ^| findstr 4723') do @echo %~nxa

输出:

10396

如果你想在Windows中删除该值的第四个数字,即“LISTENING”,则使用以下命令。

命令:

for /f "tokens=4" %a in ('netstat -aon ^| findstr 4723') do @echo %~nxa

输出:

听取中


1
有没有关于过滤唯一PID的建议?因为该命令有时会多次返回相同的进程。 - Krzysztof Krzeszewski

10

如果您想通过编程方式实现此操作,可以在PowerShell脚本中使用以下选项:

$processPID =  $($(netstat -aon | findstr "9999")[0] -split '\s+')[-1]
taskkill /f /pid $processPID

然而,请注意,你提供的信息越准确,PID 结果就越精确。如果你知道该端口所在的主机,那么你可以大大缩小搜索范围。使用 netstat -aon | findstr "0.0.0.0:9999" 仅会返回一个应用程序且很可能是正确的。仅根据端口号进行搜索可能会导致你返回一些仅恰好包含 9999 的进程,例如:

TCP    0.0.0.0:9999                        0.0.0.0:0       LISTENING       15776
UDP    [fe80::81ad:9999:d955:c4ca%2]:1900  *:*                             12331
通常情况下,最有可能的候选进程会排在第一位,但如果进程在运行脚本之前已经结束,则你可能会得到 PID 12331,从而误杀错误的进程。

5

在修改脚本后,我得到了以下操作。将其复制并保存为.bat文件:

FOR /F "usebackq tokens=5" %%i IN (`netstat -aon ^| find "3306"`) DO taskkill /F /PID %%i

将“find“3306””替换为需要释放的端口号。然后以管理员身份运行该文件,它将结束在此端口上运行的所有进程。


2

PowerShell(与Core兼容)一行代码可简化复制粘贴场景:

netstat -aon | Select-String 8080 | ForEach-Object { $_ -replace '\s+', ',' } | ConvertFrom-Csv -Header @('Empty', 'Protocol', 'AddressLocal', 'AddressForeign', 'State', 'PID') | ForEach-Object { $portProcess = Get-Process | Where-Object Id -eq $_.PID; $_ | Add-Member -NotePropertyName 'ProcessName' -NotePropertyValue $portProcess.ProcessName; Write-Output $_ } | Sort-Object ProcessName, State, Protocol, AddressLocal, AddressForeign | Select-Object  ProcessName, State, Protocol, AddressLocal, AddressForeign | Format-Table

输出:

ProcessName State     Protocol AddressLocal AddressForeign
----------- -----     -------- ------------ --------------
System      LISTENING TCP      [::]:8080    [::]:0
System      LISTENING TCP      0.0.0.0:8080 0.0.0.0:0

同样的代码,更加适合开发者使用:

$Port = 8080

# Get PID's listening to $Port, as PSObject
$PidsAtPortString = netstat -aon `
  | Select-String $Port
$PidsAtPort = $PidsAtPortString `
  | ForEach-Object { `
      $_ -replace '\s+', ',' `
  } `
  | ConvertFrom-Csv -Header @('Empty', 'Protocol', 'AddressLocal', 'AddressForeign', 'State', 'PID')

# Enrich port's list with ProcessName data
$ProcessesAtPort = $PidsAtPort `
  | ForEach-Object { `
    $portProcess = Get-Process `
      | Where-Object Id -eq $_.PID; `
    $_ | Add-Member -NotePropertyName 'ProcessName' -NotePropertyValue $portProcess.ProcessName; `
    Write-Output $_;
  }

# Show output
$ProcessesAtPort `
  | Sort-Object    ProcessName, State, Protocol, AddressLocal, AddressForeign `
  | Select-Object  ProcessName, State, Protocol, AddressLocal, AddressForeign `
  | Format-Table

我们已经知道它是使用端口的 "java"。目标是找到 PID,以便我们可以终止它。 - sf_jeff

0

这可以通过端口号来查找PID。

lsof -i tcp:port_number

2
在输入命令后,我得到了“'lsof' 不是内部或外部命令”。 - Srinivas
适用于Linux操作系统。 - Mahaveer Jangir
7
这个问题关于 Windows。 - acaruci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接