Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which PID listens on a given port in c#

Tags:

c#

windows

What is the easiest way to get a PID that listens on a given port in C#? Basically, I want to make sure that my service is running and listens on a port I have provided it. If there is an easier way than parsing netstat output it will be great.

like image 755
Philip Derbeko Avatar asked Feb 23 '09 12:02

Philip Derbeko


People also ask

Which PID is listening on a port?

The Netstat.exe command has a switch, that can display the process identifier (PID) that is associated with each connection to identify port conflicts. This information can be used to determine which process (program) listens on a given port. Using Netstat command: Open a terminal.

What listens to port?

The listening port listens to applications or processes on the network port. It is acting just like the communication endpoint. Using the firewall, we can open or closed each listening port. The open port can be defined as a network port used to accept incoming packets from remote locations.

How many process can listen on a port?

Only one application can actively listen on a port. But that application can bequeath its connection to another process.

What is port and PID?

Process id(aka PID) uniquely identifies a process running on a computer. Port number uniquely identifies a process running on a computer in a network.


1 Answers

from win XP SP2 onwards you can P/Invoke to GetExtendedTcpTable

Using This person's kind work to flesh out the signature (the PInvoke.net spec is incomplete) here is a (rough and poor at error checking) example

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;
}
like image 154
ShuggyCoUk Avatar answered Sep 28 '22 22:09

ShuggyCoUk