c# - 哪个 PID 在 c# 中的给定端口上监听

标签 c# windows

在 C# 中获取监听给定端口的 PID 的最简单方法是什么? 基本上,我想确保我的服务正在运行并监听我提供的端口。 如果有比解析 netstat 输出更简单的方法,那就太好了。

最佳答案

从 win XP SP2 开始,您可以 P/Invoke 到 GetExtendedTcpTable

使用 This person's充实签名的好心工作(PInvoke.net 规范不完整)这里是一个(粗略且不擅长错误检查)示例

using System;
using System.Runtime.InteropServices;

public enum TCP_TABLE_CLASS : int
{
    TCP_TABLE_BASIC_LISTENER,
    TCP_TABLE_BASIC_CONNECTIONS,
    TCP_TABLE_BASIC_ALL,
    TCP_TABLE_OWNER_PID_LISTENER,
    TCP_TABLE_OWNER_PID_CONNECTIONS,
    TCP_TABLE_OWNER_PID_ALL,
    TCP_TABLE_OWNER_MODULE_LISTENER,
    TCP_TABLE_OWNER_MODULE_CONNECTIONS,
    TCP_TABLE_OWNER_MODULE_ALL
} 

[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW_OWNER_PID
{
    public uint state;
    public uint localAddr;
    public byte localPort1;
    public byte localPort2;
    public byte localPort3;
    public byte localPort4;
    public uint remoteAddr;
    public byte remotePort1;
    public byte remotePort2;
    public byte remotePort3;
    public byte remotePort4;
    public int owningPid;

    public ushort LocalPort
{
        get
        {
            return BitConverter.ToUInt16(
                new byte[2] { localPort2, localPort1}, 0);
        }
    }

    public ushort RemotePort
    {
        get
        {
            return BitConverter.ToUInt16(
                new byte[2] { remotePort2, remotePort1}, 0);
        }
    }
}

[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPTABLE_OWNER_PID
{
    public uint dwNumEntries;
    MIB_TCPROW_OWNER_PID table;
}

[DllImport("iphlpapi.dll", SetLastError=true)]
static extern uint GetExtendedTcpTable(IntPtr pTcpTable, 
    ref int dwOutBufLen, 
    bool sort, 
    int ipVersion, 
    TCP_TABLE_CLASS tblClass,
    int reserved);

public static MIB_TCPROW_OWNER_PID[] GetAllTcpConnections()
{
    MIB_TCPROW_OWNER_PID[] tTable;
    int AF_INET = 2;    // IP_v4
    int buffSize = 0;

    // how much memory do we need?
    uint ret = GetExtendedTcpTable(IntPtr.Zero, 
        ref buffSize, 
        true, 
        AF_INET, 
        TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL,
        0);        
    if (ret != 0 && ret != 122) // 122 insufficient buffer size
        throw new Exception("bad ret on check " + ret);
    IntPtr buffTable = Marshal.AllocHGlobal(buffSize);

    try
    {
        ret = GetExtendedTcpTable(buffTable, 
            ref buffSize, 
            true, 
            AF_INET, 
            TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 
            0);
        if (ret != 0)
            throw new Exception("bad ret "+ ret);        

        // get the number of entries in the table
        MIB_TCPTABLE_OWNER_PID tab = 
            (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(
                buffTable, 
                typeof(MIB_TCPTABLE_OWNER_PID));
         IntPtr rowPtr = (IntPtr)((long)buffTable + 
             Marshal.SizeOf(tab.dwNumEntries));
        tTable = new MIB_TCPROW_OWNER_PID[tab.dwNumEntries];

        for (int i = 0; i < tab.dwNumEntries; i++)
        {
            MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal
                .PtrToStructure(rowPtr, typeof(MIB_TCPROW_OWNER_PID));
            tTable[i] = tcpRow;
            // next entry
            rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(tcpRow));   
        }
    }
    finally
    {
        // Free the Memory
        Marshal.FreeHGlobal(buffTable);
    }
    return tTable;
}

关于c# - 哪个 PID 在 c# 中的给定端口上监听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/577433/

相关文章:

c# - 写入工作表导致 "name already taken"

c# - 任务状态 :Waiting for activation -DownloadStringTaskAsync -WP8

c# - 是否可以在不将源移动到目标的情况下在 C# 中进行拖放?

c# - 在 web.config 值中使用 HTML 下标

c# - 在datagridview c#中过滤数据

c - Windows 上带有 DLL 的动态模块

windows - 生成唯一的机器 ID

c# - 验证是否安装了 Visual C++ 2008 SP1 Redistributable Package 而不在 Windows 注册表中搜索?

c# - 将父类(super class)转换为子类

c# - 如何使 WPF 窗口标题的文本长度大于 255 个字符?