【问题标题】:Finding TCP ports used by application查找应用程序使用的 TCP 端口
【发布时间】:2011-09-23 21:33:37
【问题描述】:

好的,所以我正在扩展我公司的 flexlm 供应商守护程序,以便对客户端应用程序更具启发性。

我需要能够在客户端连接之前找出 lmgrd 正在侦听的端口。 API 文档似乎相当贫瘠,我相信他们将大部分代码保存在编译后的形式中,所以我不能只看他们的源代码。

是否可以调用 Windows API 的强大功能来找出特定进程正在使用哪些端口?如果 Sysinternals 的 Process Explorer 可以做到,我应该可以做到,对吧?什么是一些示例代码?

它需要支持 Windows XP 及更高版本,因为我们的许多客户尚未升级。

我应该注意到,事实证明 FLEX 支持从许可证文件中提取端口。我面前没有代码,但知道这不是找出供应商守护程序/lmgrd 正在运行哪些端口的最佳方法。

【问题讨论】:

    标签: windows api process tcp port


    【解决方案1】:

    GetTcpTable2 -- 见下文

    GetTcpTable2 function

    GetTcpTable 函数检索 IPv4 TCP 连接表。

    这将填充 MIB_TCPTABLE 结构。

    typedef struct _MIB_TCPTABLE {
      DWORD      dwNumEntries;
      MIB_TCPROW table[ANY_SIZE];
    } MIB_TCPTABLE, *PMIB_TCPTABLE;
    

    现在是 MIB_TCPROW

    typedef struct _MIB_TCPROW {
      DWORD dwState;
      DWORD dwLocalAddr;
      DWORD dwLocalPort;
      DWORD dwRemoteAddr;
      DWORD dwRemotePort;
    } MIB_TCPROW, *PMIB_TCPROW;
    

    重要提示

    您还需要使用 GetTcpTable2 来获取关联的相应 PID。

    typedef struct _MIB_TCPROW2 {
      DWORD                        dwState;
      DWORD                        dwLocalAddr;
      DWORD                        dwLocalPort;
      DWORD                        dwRemoteAddr;
      DWORD                        dwRemotePort;
      DWORD                        dwOwningPid;
      TCP_CONNECTION_OFFLOAD_STATE dwOffloadState;
    } MIB_TCPROW2, *PMIB_TCPROW2;
    

    dwOwningPid

    【讨论】:

    • 废话。没办法。似乎 GetTcpTable2 函数是 Vista 和更高版本的函数。我应该指定它至少应该与 Windows XP 一起工作,因为我们的许多客户还没有升级。我会更新我原来的帖子。很棒的发现,我必须说。
    • 所以...看起来最接近的 Windows XP 版本是 AllocateAndGetTcpExTableFromStack msdn.microsoft.com/en-us/library/aa365804(v=vs.85).aspx
    • 应该使用 GetTcpTable 或 GetExtendedTcpTable 函数来检索 TCP 连接表,而不是使用 AllocateAndGetTcpExTableFromStack 函数。注意 AllocateAndGetTcpExTableFromStack 函数已弃用,并且在 Windows Vista 及更高版本上不受支持。在为 Windows Vista 及更高版本发布的 Microsoft Windows 软件开发工具包 (SDK) 上,AllocateAndGetTcpExTableFromStack 的函数原型仍定义在 Iphlpapi.h 头文件中,以便继续支持 Windows Server 2003 和 Windows XP。
    • 使用:GetExtendedTcpTable 和 GetOwnerModuleFromTcpEntry
    • 刚刚找到 GetExtendedTcpTable。太棒了!
    【解决方案2】:

    这是我最终得到的代码,适用于在我之后遇到此问题的任何人

    #include "stdafx.h"
    #include <windows.h>
    #include <iphlpapi.h>
    
    // These are just for the ntohl function in the printf below
    #include <winsock.h>
    #pragma comment(lib, "Ws2_32.lib")
    
    DWORD (WINAPI *pGetExtendedTcpTable)(
      PVOID pTcpTable,
      PDWORD pdwSize,
      BOOL bOrder,
      ULONG ulAf,
      TCP_TABLE_CLASS TableClass,
      ULONG Reserved
    );
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        MIB_TCPTABLE_OWNER_PID *pTCPInfo;
        MIB_TCPROW_OWNER_PID *owner;
        DWORD size;
        DWORD dwResult;
    
        HMODULE hLib = LoadLibrary("iphlpapi.dll");
    
        pGetExtendedTcpTable = (DWORD (WINAPI *)(PVOID, PDWORD, BOOL, ULONG, TCP_TABLE_CLASS, ULONG))
            GetProcAddress(hLib, "GetExtendedTcpTable");
    
        if (!pGetExtendedTcpTable)
        {
            printf("Could not load iphlpapi.dll. This application is for Windows XP SP2 and up.\n");
            return 1;
        }
    
        dwResult = pGetExtendedTcpTable(NULL,     &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
        pTCPInfo = (MIB_TCPTABLE_OWNER_PID*)malloc(size);
        dwResult = pGetExtendedTcpTable(pTCPInfo, &size, false, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0);
    
        if (dwResult != NO_ERROR)
        {
            printf("Couldn't get our IP table");
            return 2;
        }
    
        printf("Iterating though table:\n");
        for (DWORD dwLoop = 0; dwLoop < pTCPInfo->dwNumEntries; dwLoop++)
        {
            owner = &pTCPInfo->table[dwLoop];
    
            printf("  PID: %5u - Port: %5u\n", owner->dwOwningPid, ntohs(owner->dwLocalPort));
        }
    
        // Pause a moment
        printf("Done Processing\n");
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      在最坏的情况下,您总是可以解析以下输出:

      netstat -bna
      

      【讨论】:

      • 有趣的想法。更多可以找到该应用程序的逆向工程版本。我已经使用了旧的 Winternals 源代码,并将看看那个人是如何实现他的 TCPView 应用程序的。
      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2022-01-15
      相关资源
      最近更新 更多