.NET Core如何获取当前进程监听端口?有无高效内置方法?
如何在.NET中高效获取带进程信息的监听端口
嘿,这个问题我之前折腾过好一阵子!你说得没错,调用netstat确实又慢又麻烦,而IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners()只能拿到TCP监听端点,完全没进程相关的信息,确实头疼。
遗憾的是,.NET里并没有单一的内置API能直接返回带进程ID/名称的TCP监听端口,但我们可以用组合的方式实现,比调用netstat高效得多,而且都是用.NET的内置能力:
Windows平台:用WMI查询(推荐)
Windows自带的WMI服务可以直接查询到监听端口对应的进程信息,.NET通过System.Management命名空间就能调用,步骤如下:
首先添加
System.Management引用:- .NET Framework:直接在项目引用里勾选
System.Management - .NET Core/.NET 5+:通过NuGet安装
System.Management包
- .NET Framework:直接在项目引用里勾选
示例代码:
using System; using System.Diagnostics; using System.Management; class PortListenerInfo { static void Main() { // 查询所有处于监听状态的TCP连接,获取端口和进程ID var tcpQuery = new SelectQuery("SELECT LocalPort, ProcessId FROM Win32_TCPConnection WHERE State = 'Listen'"); using (var searcher = new ManagementObjectSearcher(tcpQuery)) { foreach (var connectionObj in searcher.Get()) { int port = Convert.ToInt32(connectionObj["LocalPort"]); int pid = Convert.ToInt32(connectionObj["ProcessId"]); try { // 通过进程ID获取进程名称 var process = Process.GetProcessById(pid); Console.WriteLine($"端口 {port} 被进程 {process.ProcessName} (PID: {pid}) 监听"); } catch (ArgumentException) { // 进程可能已经退出,忽略即可 Console.WriteLine($"端口 {port} 被已退出的进程 (PID: {pid}) 监听"); } } } } }
这种方式比调用netstat再解析输出快得多,而且是Windows平台的原生内置方案。
跨平台场景(Linux/macOS)
如果需要跨平台支持,.NET 5+可以通过读取系统文件来实现:
- Linux:读取
/proc/net/tcp和/proc/net/tcp6文件,解析其中的端口和进程ID(inode对应进程的文件描述符) - macOS:可以调用
lsof命令,但这和netstat类似,不过解析起来更简单;或者用sysctl获取网络信息
不过这些方式需要自己做解析,不如Windows的WMI方便,但胜在跨平台。
补充说明
你之前用的GetActiveTcpListeners()可以用来快速获取所有监听端口,但要关联进程信息,还是得结合上面的方法。相比调用netstat,这些方案都避免了启动外部进程,性能提升很明显。
内容的提问来源于stack exchange,提问作者Hourglass
相关产品推荐
相关产品推荐

