Windows服务(SYSTEM用户)下如何用GetTcpTable2获取全量套接字及PID
解决方案:使用GetExtendedTcpTable获取全量TCP连接及PID
以SYSTEM身份运行的Windows服务本身具备足够权限获取所有进程的TCP连接,无需模拟。问题出在GetTcpTable2的查询范围限制,改用GetExtendedTcpTable并指定正确参数即可解决。
核心原因
GetTcpTable2默认返回的连接信息未明确覆盖所有会话的进程,而GetExtendedTcpTable支持通过参数指定获取所有带进程ID(PID)的TCP连接,完全适配SYSTEM服务的运行环境。
修改后的代码示例
#include <windows.h> #include <iphlpapi.h> #include <stdio.h> #pragma comment(lib, "iphlpapi.lib") int main() { PMIB_TCPTABLE_OWNER_PID pTcpTable = NULL; ULONG ulSize = 0; DWORD dwResult; // 先获取所需内存大小 dwResult = GetExtendedTcpTable(NULL, &ulSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); if (dwResult != ERROR_INSUFFICIENT_BUFFER) { printf("GetExtendedTcpTable 初始调用失败,错误码: %d\n", dwResult); return 1; } // 分配内存 pTcpTable = (PMIB_TCPTABLE_OWNER_PID)LocalAlloc(LMEM_FIXED, ulSize); if (pTcpTable == NULL) { printf("内存分配失败\n"); return 1; } // 获取TCP连接表 dwResult = GetExtendedTcpTable(pTcpTable, &ulSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); if (dwResult != NO_ERROR) { printf("GetExtendedTcpTable 调用失败,错误码: %d\n", dwResult); LocalFree(pTcpTable); return 1; } // 遍历并输出连接信息 printf("TCP连接数: %d\n", pTcpTable->dwNumEntries); for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) { printf("索引: %d\n", i); printf("本地IP: %u.%u.%u.%u\n", (pTcpTable->table[i].dwLocalAddr >> 0) & 0xFF, (pTcpTable->table[i].dwLocalAddr >> 8) & 0xFF, (pTcpTable->table[i].dwLocalAddr >> 16) & 0xFF, (pTcpTable->table[i].dwLocalAddr >> 24) & 0xFF); printf("本地端口: %d\n", ntohs((u_short)pTcpTable->table[i].dwLocalPort)); printf("远程IP: %u.%u.%u.%u\n", (pTcpTable->table[i].dwRemoteAddr >> 0) & 0xFF, (pTcpTable->table[i].dwRemoteAddr >> 8) & 0xFF, (pTcpTable->table[i].dwRemoteAddr >> 16) & 0xFF, (pTcpTable->table[i].dwRemoteAddr >> 24) & 0xFF); printf("远程端口: %d\n", ntohs((u_short)pTcpTable->table[i].dwRemotePort)); printf("状态: %d\n", pTcpTable->table[i].dwState); printf("所属PID: %d\n\n", pTcpTable->table[i].dwOwningPid); } LocalFree(pTcpTable); return 0; }
关键参数说明
TCP_TABLE_OWNER_PID_ALL: 指定获取所有状态的TCP连接,并包含所属进程PID。AF_INET: 针对IPv4连接,若需IPv6可改为AF_INET6,对应使用MIB_TCP6TABLE_OWNER_PID结构。- 第三个参数设为
TRUE: 返回有序的连接表,不影响功能但便于遍历。
内容的提问来源于stack exchange,提问作者aksh
相关产品推荐
相关产品推荐

