You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Windows C++ API获取应用程序的监听端口

Windows下获取指定应用监听端口的API及实现方案

核心依赖API

Windows官方提供的IP Helper库中,GetExtendedTcpTable、GetExtendedUdpTable两个API是实现进程与端口关联查询的核心,需引入头文件iphlpapi.h,编译时链接iphlpapi.lib。
这两个API返回的系统TCP/UDP连接表中,每个条目都包含对应连接/监听端口绑定的进程ID(PID),匹配目标应用的PID即可提取到对应的端口信息。

具体实现步骤

  • 第一步:获取目标应用的PID
    可通过CreateToolhelp32SnapshotAPI枚举系统进程,匹配目标应用的进程名获取对应PID,也可以直接传入用户指定的PID。
  • 第二步:获取TCP端口关联表
    调用GetExtendedTcpTable,传入TCP_TABLE_OWNER_PID_LISTENER参数专门获取监听状态的TCP端口关联信息,可通过AF_INET/AF_INET6参数区分IPv4/IPv6协议。
  • 第三步:获取UDP端口关联表
    调用GetExtendedUdpTable,传入UDP_TABLE_OWNER_PID参数获取所有UDP端口的关联信息。
  • 第四步:匹配PID提取端口
    遍历TCP、UDP端口关联表的所有条目,匹配目标应用的PID,提取对应的端口号即可。

C语言实现示例

#include <windows.h>
#include <iphlpapi.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <winsock.h>

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

// 根据进程名获取对应PID
DWORD GetPidByProcessName(const WCHAR* processName) {
    PROCESSENTRY32 pe32;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) return 0;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    if (!Process32First(hSnapshot, &pe32)) {
        CloseHandle(hSnapshot);
        return 0;
    }
    do {
        if (_wcsicmp(pe32.szExeFile, processName) == 0) {
            CloseHandle(hSnapshot);
            return pe32.th32ProcessID;
        }
    } while (Process32Next(hSnapshot, &pe32));
    CloseHandle(hSnapshot);
    return 0;
}

// 打印目标PID对应的TCP监听端口
void ListTcpListenPortsByPid(DWORD targetPid) {
    PMIB_TCPTABLE_OWNER_PID pTcpTable = NULL;
    DWORD dwSize = 0;

    // 首次调用获取所需缓冲区大小
    if (GetExtendedTcpTable(NULL, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0) == ERROR_INSUFFICIENT_BUFFER) {
        pTcpTable = (PMIB_TCPTABLE_OWNER_PID)HeapAlloc(GetProcessHeap(), 0, dwSize);
        if (pTcpTable == NULL) return;
    } else return;

    // 二次调用获取实际端口数据
    if (GetExtendedTcpTable(pTcpTable, &dwSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_LISTENER, 0) == NO_ERROR) {
        for (DWORD i = 0; i < pTcpTable->dwNumEntries; i++) {
            if (pTcpTable->table[i].dwOwningPid == targetPid) {
                printf("TCP监听端口:%d\n", ntohs((u_short)pTcpTable->table[i].dwLocalPort));
            }
        }
    }
    HeapFree(GetProcessHeap(), 0, pTcpTable);
}

int main() {
    // 示例:查询chrome.exe的监听端口,替换为你的目标进程名即可
    DWORD targetPid = GetPidByProcessName(L"chrome.exe");
    if (targetPid == 0) {
        printf("未找到目标进程\n");
        return 1;
    }
    printf("目标进程PID:%d\n", targetPid);
    ListTcpListenPortsByPid(targetPid);
    // UDP端口查询逻辑与TCP类似,调用GetExtendedUdpTable即可实现
    return 0;
}

注意事项

  • 示例仅实现了IPv4下的TCP监听端口查询,如需IPv6支持,将AF_INET替换为AF_INET6,对应表结构替换为MIB_TCP6TABLE_OWNER_PID即可。
  • 如需查询已建立连接的端口而非监听端口,将TCP_TABLE_OWNER_PID_LISTENER替换为TCP_TABLE_OWNER_PID_CONNECTIONS即可。
  • 临时排查无需代码实现的场景,可直接在cmd中执行netstat -ano | findstr 目标PID,快速查询对应端口。
  • 拿到目标端口后,可在Wireshark中通过tcp.port == 目标端口/udp.port == 目标端口过滤规则筛选对应应用的数据包,也可在Scapy中通过端口匹配过滤流量。

内容的提问来源于stack exchange,提问作者yellow up

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:09:03