获取Windows下某进程监听的TCP/UDP端口

1、在Windows下用CMD netstat命令可以获得当前进程监听端口号的信息,如netstat -ano可以看到IP、port、状态和监听的PID。

那么可以执行CMD这个进程得到监听的端口号信息,C#代码如下:

            //进程id

            int pid = ProcInfo.ProcessID;

            

            //存放进程使用的端口号链表

            List<int> ports = new List<int>();



            Process pro = new Process();

            pro.StartInfo.FileName = "cmd.exe";

            pro.StartInfo.UseShellExecute = false;

            pro.StartInfo.RedirectStandardInput = true;

            pro.StartInfo.RedirectStandardOutput = true;

            pro.StartInfo.RedirectStandardError = true;

            pro.StartInfo.CreateNoWindow = true;

            pro.Start();

            pro.StandardInput.WriteLine("netstat -ano");

            pro.StandardInput.WriteLine("exit");

            Regex reg = new Regex("\\s+", RegexOptions.Compiled);

            string line = null;

            ports.Clear();

            while ((line = pro.StandardOutput.ReadLine()) != null)

            {

                line = line.Trim();

                if (line.StartsWith("TCP", StringComparison.OrdinalIgnoreCase))

                {

                    line = reg.Replace(line, ",");

                    string[] arr = line.Split(',');

                    if (arr[4] == pid.ToString())

                    {

                        string soc = arr[1];

                        int pos = soc.LastIndexOf(':');

                        int pot = int.Parse(soc.Substring(pos + 1));

                        ports.Add(pot);

                    }

                }

                else if (line.StartsWith("UDP", StringComparison.OrdinalIgnoreCase))

                {

                    line = reg.Replace(line, ",");

                    string[] arr = line.Split(',');

                    if (arr[3] == pid.ToString())

                    {

                        string soc = arr[1];

                        int pos = soc.LastIndexOf(':');

                        int pot = int.Parse(soc.Substring(pos + 1));

                        ports.Add(pot);

                    }

                }

            }

            pro.Close();

2、如果不执行CMD进程,如何获得?可以参考这篇文章http://www.cnblogs.com/BoyXiao/archive/2012/02/20/2359273.html

文章介绍了使用Windows API获得进程和端口的映射关系:

(1)根据进程 ID 获得该进程所打开的所有的 TCP 和 UDP 端口。

(2)根据端口号来获得打开该端口的进程。

C语言代码如下:

获取Windows下某进程监听的TCP/UDP端口
// ProcessorPort.cpp : 定义 DLL 应用程序的导出函数。

//



#include "stdafx.h"



#include <Windows.h>   

#include <Psapi.h>   

#include <Iprtrmib.h>   

#include <Winsock2.h>



#pragma  comment(lib,"Psapi.lib")

#pragma  comment(lib,"Iphlpapi.Lib")

#pragma  comment(lib,"WS2_32.lib")



enum TcpOrUdp

{

    TcpType,   

    UdpType  

};



typedef struct  

{  

    DWORD dwState;      //连接状态   

    DWORD dwLocalAddr;  //本地地址   

    DWORD dwLocalPort;  //本地端口   

    DWORD dwRemoteAddr; //远程地址   

    DWORD dwRemotePort; //远程端口   

    DWORD dwProcessId;  //进程标识 

}MIB_TCPEXROW,*PMIB_TCPEXROW;  





typedef struct  

{  

    DWORD dwLocalAddr;  //本地地址   

    DWORD dwLocalPort;  //本地端口   

    DWORD dwProcessId;  //进程标识   



}MIB_UDPEXROW,*PMIB_UDPEXROW;  





typedef struct  

{  

    DWORD dwState;      //连接状态   

    DWORD dwLocalAddr;  //本地地址   

    DWORD dwLocalPort;  //本地端口   

    DWORD dwRemoteAddr; //远程地址   

    DWORD dwRemotePort; //远程端口   

    DWORD dwProcessId;  //进程标识   

    DWORD Unknown;      //待定标识

}MIB_TCPEXROW_VISTA,*PMIB_TCPEXROW_VISTA;  





typedef struct  

{  

    DWORD dwNumEntries;  

    MIB_TCPEXROW table[ANY_SIZE];

}MIB_TCPEXTABLE,*PMIB_TCPEXTABLE;  





typedef struct  

{  

    DWORD dwNumEntries;  

    MIB_TCPEXROW_VISTA table[ANY_SIZE];

}MIB_TCPEXTABLE_VISTA,*PMIB_TCPEXTABLE_VISTA;  





typedef struct  

{  

    DWORD dwNumEntries;  

    MIB_UDPEXROW table[ANY_SIZE];

}MIB_UDPEXTABLE,*PMIB_UDPEXTABLE;  





//=====================================================================================//   

//Name: DWORD AllocateAndGetTcpExTableFromStack()                                      //                                                                //   

//Descripion: 该函数仅仅只在 Windows XP,Windows Server 2003 下有效                    //   

//=====================================================================================//   

typedef DWORD (WINAPI *PFNAllocateAndGetTcpExTableFromStack)(  

    PMIB_TCPEXTABLE *pTcpTabel,  

    bool bOrder,  

    HANDLE heap,  

    DWORD zero,  

    DWORD flags  

    );  



//=====================================================================================//   

//Name: DWORD AllocateAndGetUdpExTableFromStack()                                      //   

//Descripion: 该函数仅仅只在 XP,Windows Server 2003 下有效                            //   

//=====================================================================================//   

typedef DWORD (WINAPI *PFNAllocateAndGetUdpExTableFromStack)(  

    PMIB_UDPEXTABLE *pUdpTable,  

    bool bOrder,  

    HANDLE heap,  

    DWORD zero,  

    DWORD flags  

    );  



//=====================================================================================//   

//Name: DWORD InternalGetTcpTable2()                                                   //   

//Descripion: 该函数在 Windows Vista 以及 Windows 7 下面效                             //   

//=====================================================================================//   

typedef DWORD (WINAPI *PFNInternalGetTcpTable2)(  

    PMIB_TCPEXTABLE_VISTA *pTcpTable_Vista,  

    HANDLE heap,  

    DWORD flags  

    );  



//=====================================================================================//   

//Name: DWORD InternalGetUdpTableWithOwnerPid()                                        //   

//Descripion: 该函数在 Windows Vista 以及 Windows 7 下面效                             //   

//=====================================================================================//   

typedef DWORD (WINAPI *PFNInternalGetUdpTableWithOwnerPid)(  

    PMIB_UDPEXTABLE *pUdpTable,  

    HANDLE heap,  

    DWORD flags  

    );  





//=====================================================================================//   

//Name: DWORD GetProcessIdByPort()                                                     //   

//Descripion: 根据端口号得到打开该端口号的进程ID(支持 XP,Server 2003,Vista,Win7)   //   

//=====================================================================================//   

extern "C" __declspec(dllexport) DWORD __stdcall GetProcessIdByPort(TcpOrUdp type, DWORD dwPort)  

{  

    HMODULE hModule = LoadLibraryW(L"iphlpapi.dll");  

    if (hModule == NULL)  

    {  

        return 0;  

    }  



    if(type == TcpType)  

    {  

        // 表明查询的是 TCP 信息   

        PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;  

        pAllocateAndGetTcpExTableFromStack =   

            (PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack");  

        if (pAllocateAndGetTcpExTableFromStack != NULL)  

        {  

            // 表明为 XP 或者 Server 2003 操作系统   

            PMIB_TCPEXTABLE pTcpExTable = NULL;  

            if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return 0;  

            }  



            for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只查询我们需要的进程数据   

                if(dwPort == ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort))  

                {  

                    DWORD dwProcessId = pTcpExTable->table[i].dwProcessId;  

                    if (pTcpExTable)  

                    {  

                        HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                    }  



                    FreeLibrary(hModule);  

                    hModule = NULL;  



                    return dwProcessId;  

                }  

            }  



            if (pTcpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pTcpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return 0;  

        }  

        else  

        {  

            // 表明为 Vista 或者 7 操作系统   

            PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL;  

            PFNInternalGetTcpTable2 pInternalGetTcpTable2 =   

                (PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");  

            if (pInternalGetTcpTable2 == NULL)  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return 0;  

            }  



            if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1))  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return 0;  

            }  



            for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只查询我们需要的进程数据   

                if(dwPort == ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort))  

                {  

                    DWORD dwProcessId = pTcpExTable->table[i].dwProcessId;  

                    if (pTcpExTable)  

                    {  

                        HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                    }  



                    FreeLibrary(hModule);  

                    hModule = NULL;  



                    return dwProcessId;  

                }  

            }  



            if (pTcpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pTcpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return 0;  

        }  

    }  

    else if(type == UdpType)  

    {  

        // 表明查询的是 UDP 信息   

        PMIB_UDPEXTABLE pUdpExTable = NULL;  

        PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;  

        pAllocateAndGetUdpExTableFromStack =   

            (PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");  

        if (pAllocateAndGetUdpExTableFromStack != NULL)  

        {  

            // 表明为 XP 或者 Server 2003 操作系统   

            if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)  

            {  

                if (pUdpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return 0;  

            }  



            for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只查询我们需要的进程数据   

                if (dwPort == ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort))  

                {  

                    DWORD dwProcessId = pUdpExTable->table[i].dwProcessId;  

                    if (pUdpExTable)  

                    {  

                        HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                    }  



                    FreeLibrary(hModule);  

                    hModule = NULL;  



                    return dwProcessId;  

                }  

            }  



            if (pUdpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pUdpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return 0;  

        }  

        else  

        {  

            // 表明为 Vista 或者 7 操作系统   

            PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;  

            pInternalGetUdpTableWithOwnerPid =   

                (PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");  

            if (pInternalGetUdpTableWithOwnerPid != NULL)  

            {  

                if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1))  

                {  

                    if (pUdpExTable)  

                    {  

                        HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                    }  



                    FreeLibrary(hModule);  

                    hModule = NULL;  



                    return 0;  

                }  



                for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)  

                {  

                    // 过滤掉数据,只查询我们需要的进程数据   

                    if (dwPort == ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort))  

                    {  

                        DWORD dwProcessId = pUdpExTable->table[i].dwProcessId;  

                        if (pUdpExTable)  

                        {  

                            HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                        }  



                        FreeLibrary(hModule);  

                        hModule = NULL;  



                        return dwProcessId;  

                    }  

                }  

            }  



            if (pUdpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pUdpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return 0;  

        }  

    }  

    else  

    {  

        FreeLibrary(hModule);  

        hModule = NULL;  



        return -1;  

    }  

}  





//===========================================================================================//   

//Name: DWORD GetAllPortByProcessId()                                                        //   

//Descripion: 根据进程ID得到该进程所打开的所有的端口号,并且在 dwAllPort 数组中返回所有端口号//   

//            其中 dwMaxLen 为数组的长度,函数的返回值为进程所打开的端口的数目               //   

//            (支持 XP,Server 2003,Vista,Win7)                                            //   

//===========================================================================================//   

extern "C" __declspec(dllexport) DWORD __stdcall GetAllPortByProcessId(TcpOrUdp type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen)  

{  

    DWORD dwPortCount = 0;  

    HMODULE hModule = LoadLibraryW(L"iphlpapi.dll");  

    if (hModule == NULL)  

    {  

        return dwPortCount;  

    }  



    if(type == TcpType)  

    {  

        // 表明查询的是 UDP 信息   

        PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;  

        pAllocateAndGetTcpExTableFromStack = (PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack");  

        if (pAllocateAndGetTcpExTableFromStack != NULL)  

        {  

            // 表明为 XP 或者 Server 2003 操作系统   

            PMIB_TCPEXTABLE pTcpExTable = NULL;  

            if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return dwPortCount;  

            }  



            for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只获取我们要查询的进程的 Port 信息   

                if(dwProcessId == pTcpExTable->table[i].dwProcessId)  

                {  

                    if(dwPortCount < dwMaxLen)  

                    {  

                        dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);  

                        dwPortCount++;  

                    }  

                }  

            }  



            if (pTcpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pTcpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return dwPortCount;  

        }  

        else  

        {  

            // 表明为 Vista 或者 7 操作系统   

            PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL;  

            PFNInternalGetTcpTable2 pInternalGetTcpTable2 = (PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");  

            if (pInternalGetTcpTable2 == NULL)  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return dwPortCount;  

            }  



            if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1))  

            {  

                if (pTcpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pTcpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return dwPortCount;  

            }  



            for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只获取我们要查询的进程的 TCP Port 信息   

                if(dwProcessId == pTcpExTable->table[i].dwProcessId)  

                {  

                    if(dwPortCount < dwMaxLen)  

                    {  

                        dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);  

                        dwPortCount++;  

                    }  

                }  

            }  



            if (pTcpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pTcpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return dwPortCount;  

        }  

    }  

    else if(type == UdpType)  

    {  

        // 表明查询的是 UDP 信息   

        PMIB_UDPEXTABLE pUdpExTable = NULL;  

        PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;  

        pAllocateAndGetUdpExTableFromStack = (PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");  

        if (pAllocateAndGetUdpExTableFromStack != NULL)  

        {  

            // 表明为 XP 或者 Server 2003 操作系统   

            if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)  

            {  

                if (pUdpExTable)  

                {  

                    HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                }  



                FreeLibrary(hModule);  

                hModule = NULL;  



                return dwPortCount;  

            }  



            for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)  

            {  

                // 过滤掉数据,只获取我们要查询的进程的 UDP Port信息   

                if(dwProcessId == pUdpExTable->table[i].dwProcessId)  

                {  

                    if(dwPortCount < dwMaxLen)  

                    {  

                        dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);  

                        dwPortCount++;  

                    }  

                }  

            }  



            if (pUdpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pUdpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return dwPortCount;  

        }  

        else  

        {  

            // 表明为 Vista 或者 7 操作系统   

            PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;  

            pInternalGetUdpTableWithOwnerPid = (PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");  

            if (pInternalGetUdpTableWithOwnerPid != NULL)  

            {  

                if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1))  

                {  

                    if (pUdpExTable)  

                    {  

                        HeapFree(GetProcessHeap(), 0, pUdpExTable);  

                    }  



                    FreeLibrary(hModule);  

                    hModule = NULL;  



                    return dwPortCount;  

                }  



                for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)  

                {  

                    // 过滤掉数据,只获取我们要查询的进程的 UDP Port信息   

                    if(dwProcessId == pUdpExTable->table[i].dwProcessId)  

                    {  

                        if(dwPortCount < dwMaxLen)  

                        {  

                            dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);  

                            dwPortCount++;  

                        }  

                    }  

                }  

            }  



            if (pUdpExTable)  

            {  

                HeapFree(GetProcessHeap(), 0, pUdpExTable);  

            }  



            FreeLibrary(hModule);  

            hModule = NULL;  



            return dwPortCount;  

        }  

    }  

    else  

    {  

        FreeLibrary(hModule);  

        hModule = NULL;  



        return dwPortCount;  

    }  

}  
View Code

如果要在.Net平台下使用,将其编译成DLL,使用PInvoke得到DLL导出函数就可以了。

C#测试代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;



namespace ProcessorPortDllTest

{

    public enum TcpOrUdp

    {

        TcpType,

        UdpType

    };



    public class ProcessPortHelper

    {

        [DllImport("ProcessorPort.dll",CallingConvention = CallingConvention.StdCall)]

        public extern static uint GetProcessIdByPort(TcpOrUdp type, uint dwPort);



        [DllImport("ProcessorPort.dll",CallingConvention = CallingConvention.StdCall)]

        public extern static uint GetAllPortByProcessId(TcpOrUdp type, uint dwProcessId, uint[] dwAllPort, uint dwMaxLen);

    }



    class Program

    {

        static void Main(string[] args)

        {

            uint port = 1025;

            uint processorId = ProcessPortHelper.GetProcessIdByPort(TcpOrUdp.TcpType, port);

            Console.WriteLine("Port {0} is using by processor {1}",port,processorId);



            uint processorId1 = 1072;



            uint[] TcpPorts = new uint[100];

            uint count = ProcessPortHelper.GetAllPortByProcessId(TcpOrUdp.TcpType, processorId1, TcpPorts, (uint)TcpPorts.Length);

            Console.WriteLine("Processor {0} is using TCP port: ", processorId1);

            for (uint i = 0; i < count; ++i)

            {

                Console.WriteLine(TcpPorts[i]);

            }



            uint[] UdpPorts = new uint[100];

            uint count1 = ProcessPortHelper.GetAllPortByProcessId(TcpOrUdp.UdpType, processorId1, UdpPorts, (uint)UdpPorts.Length);

            Console.WriteLine("Processor {0} is using UDP port: ", processorId1);

            for (uint i = 0; i < count1; ++i)

            {

                Console.WriteLine(UdpPorts[i]);

            }


Console.ReadKey(); } } }

 

获得进程监听TCP/UDP端口号的DLL:ProcessorPort.rar

 

你可能感兴趣的:(windows)