如何在Windows中为每个IP的PORT获取连接数?

时间:2016-11-08 08:00:30

标签: c++ windows

我一直在谷歌搜索一段时间,我似乎无法找到答案......

我正在使用 GetExtendedTcpTable()来查看我当前的连接,但我无法获得每个IP在特定端口上执行的连接数。

这有什么示例/功能吗?或者我必须创造一些东西吗?

非常感谢任何指导或示例。

度过美好的一天!

1 个答案:

答案 0 :(得分:0)

因此,使用this code from MSDN as the basis我们最终会得到一个枚举连接列表的示例,使用从远程系统到本地端口的连接数填充指向int ports的指针。

要确定特定本地端口的连接数,您只需打印出ports[port]的值。

提供的代码比C更加C++,我只使用new[]delete[]作为端口。

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) calloc(1, (x))
#define FREE(x) free((x))

int main()
{
    // Declare and initialize variables
    PMIB_TCPTABLE_OWNER_PID pTcpTable;
    int *ports; // an array of all the possible ports
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    char szRemoteAddr[128];

    struct in_addr IpAddr;

    int i;

    ports = new int[1 << (sizeof(u_short) * 8)]();

    pTcpTable = (MIB_TCPTABLE_OWNER_PID *)MALLOC(sizeof(MIB_TCPTABLE_OWNER_PID));
    if (pTcpTable == NULL) {
        printf("Error allocating memory\n");
        return 1;
    }

    dwSize = sizeof(MIB_TCPTABLE);
    // Make an initial call to GetTcpTable to
    // get the necessary size into the dwSize variable
    if ((dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_BASIC_CONNECTIONS, 0)) ==
        ERROR_INSUFFICIENT_BUFFER) {
        FREE(pTcpTable);
        pTcpTable = (MIB_TCPTABLE_OWNER_PID *)MALLOC(dwSize);
        if (pTcpTable == NULL) {
            printf("Error allocating memory\n");
            return 1;
        }
    }
    // Make a second call to GetTcpTable to get
    // the actual data we require
    if ((dwRetVal = GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_BASIC_CONNECTIONS, 0)) == NO_ERROR) {
        printf("\tNumber of entries: %d\n", (int)pTcpTable->dwNumEntries);
        for (i = 0; i < (int)pTcpTable->dwNumEntries; i++) {
            printf("\n\tTCP[%d] State: %ld - ", i,
                pTcpTable->table[i].dwState);
            if (pTcpTable->table[i].dwState != MIB_TCP_STATE_ESTAB)
                continue;

            // get the port in host order
            u_short port = ntohs((u_short)pTcpTable->table[i].dwLocalPort);
            ports[port] += 1; // increment this port

            IpAddr.S_un.S_addr = (u_long)pTcpTable->table[i].dwRemoteAddr;
            inet_ntop(AF_INET, &IpAddr, szRemoteAddr, sizeof(szRemoteAddr));
            printf("\tTCP[%d] Remote Addr: %s:%d\n", i, szRemoteAddr, ntohs((u_short)pTcpTable->table[i].dwRemotePort));
        }
    }
    else {
        printf("\tGetExtendedTcpTable failed with %d\n", dwRetVal);
        FREE(pTcpTable);
        delete[] ports;
        return 1;
    }

    if (pTcpTable != NULL) {
        FREE(pTcpTable);
        pTcpTable = NULL;
    }
    delete[] ports;
    return 0;
}

现在,如果您想要一个到端口的远程地址列表,那么当您确定端口正确时,您可以创建std::vector<std::string> remote_addresses并执行remote_addresses.push_back(szRemoteAddr)

有一种潜在的竞争条件,即在GetExtendedTcpTable的初始调用和随后调用GetExtendedTcpTable之间的另一个连接进入,这会增加dwSize的值。一般来说,要求更多的内存有助于防止这种情况发生 - 即在初次通话后,尝试要求比你需要的多8K - 但这不太可能是一个大问题。