You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中已知本地地址、端口等信息如何获取对应进程ID?

实现方案

可以直接通过C#原生类库或Win32 API封装实现,无需调用netstat等外部程序或第三方工具。

.NET 5 / .NET Core 3.0 及以上版本实现

该版本框架的System.Net.NetworkInformation命名空间已原生支持获取网络连接对应的进程ID,无需额外封装:

using System.Net;
using System.Net.NetworkInformation;

// 示例查询参数,可根据你的实际需求替换
IPAddress localAddress = IPAddress.Parse("127.0.0.1");
int localPort = 12345;
IPAddress remoteAddress = IPAddress.Parse("192.168.1.2");
int remotePort = 80;
ProtocolType protocol = ProtocolType.Tcp;
TcpState expectedState = TcpState.Established;

int targetProcessId = 0;
IPGlobalProperties ipProps = IPGlobalProperties.GetIPGlobalProperties();

if (protocol == ProtocolType.Tcp)
{
    TcpConnectionInformation[] tcpConnections = ipProps.GetActiveTcpConnections();
    foreach (var conn in tcpConnections)
    {
        // 匹配本地端点、远端端点、连接状态
        if (conn.LocalEndPoint.Address.Equals(localAddress) 
            && conn.LocalEndPoint.Port == localPort
            && conn.RemoteEndPoint.Address.Equals(remoteAddress)
            && conn.RemoteEndPoint.Port == remotePort
            && conn.State == expectedState)
        {
            targetProcessId = conn.ProcessId;
            break;
        }
    }
}
else if (protocol == ProtocolType.Udp)
{
    // UDP为无连接协议,仅匹配本地监听端点即可
    IPEndPoint[] udpListeners = ipProps.GetActiveUdpListeners();
    foreach (var listener in udpListeners)
    {
        if (listener.Address.Equals(localAddress) && listener.Port == localPort)
        {
            // UDP的ProcessId属性从.NET Core 3.0开始支持
            targetProcessId = listener.ProcessId;
            break;
        }
    }
}

if (targetProcessId > 0)
{
    Console.WriteLine($"匹配到的进程ID为:{targetProcessId}");
}

.NET Framework 版本实现

.NET Framework 原生TcpConnectionInformation未提供ProcessId属性,需要通过P/Invoke调用Windows IP Helper API的GetExtendedTcpTable、GetExtendedUdpTable函数实现,核心实现代码如下:

using System;
using System.Net;
using System.Runtime.InteropServices;

public static class IpHelper
{
    [StructLayout(LayoutKind.Sequential)]
    private struct MIB_TCPROW_OWNER_PID
    {
        public uint state;
        public uint localAddr;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] localPort;
        public uint remoteAddr;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] remotePort;
        public uint owningPid;
    }

    [DllImport("iphlpapi.dll", SetLastError = true)]
    private static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwSize, bool bOrder, int af, int tableClass, uint reserved = 0);

    private const int AF_INET = 2;
    private const int TCP_TABLE_OWNER_PID_CONNECTIONS = 5;

    public static int GetTcpConnectionProcessId(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint)
    {
        int bufferSize = 0;
        GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, false, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS);
        IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
        try
        {
            uint ret = GetExtendedTcpTable(buffer, ref bufferSize, false, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS);
            if (ret != 0) return 0;
            int rowCount = Marshal.ReadInt32(buffer);
            IntPtr rowPtr = buffer + Marshal.SizeOf(typeof(int));
            for (int i = 0; i < rowCount; i++)
            {
                MIB_TCPROW_OWNER_PID row = Marshal.PtrToStructure<MIB_TCPROW_OWNER_PID>(rowPtr);
                IPAddress rowLocalAddr = new IPAddress(row.localAddr);
                int rowLocalPort = (row.localPort[0] << 8) + row.localPort[1];
                IPAddress rowRemoteAddr = new IPAddress(row.remoteAddr);
                int rowRemotePort = (row.remotePort[0] << 8) + row.remotePort[1];
                if (rowLocalAddr.Equals(localEndPoint.Address) && rowLocalPort == localEndPoint.Port
                    && rowRemoteAddr.Equals(remoteEndPoint.Address) && rowRemotePort == remoteEndPoint.Port)
                {
                    return (int)row.owningPid;
                }
                rowPtr += Marshal.SizeOf(typeof(MIB_TCPROW_OWNER_PID));
            }
            return 0;
        }
        finally
        {
            Marshal.FreeHGlobal(buffer);
        }
    }
}

注意事项

  • 读取系统级进程的网络连接信息时,程序需要以管理员权限运行,否则部分进程ID可能返回0
  • 如果需要匹配IPv6地址,只需将上述代码中的地址族参数从AF_INET改为AF_INET6并对应调整结构体定义即可
  • UDP协议无连接状态属性,查询时仅需匹配本地监听端点信息

内容的提问来源于stack exchange,提问作者Akash Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 15:18:03