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

询问可捕获已绑定未连接套接字信息的Windows API

获取Windows中已绑定未连接的TCP套接字API方案

你提到用GetExtendedTcpTable只能拿到连接信息,其实是因为你可能指定了仅返回已连接条目的表格类型——调整参数后,这个API完全可以获取包括BOUND状态(已绑定未连接)在内的所有TCP套接字信息。

核心解决方案:使用正确的表格类型调用GetExtendedTcpTable

要捕获已绑定未连接的套接字,调用GetExtendedTcpTable时需要指定以下关键参数:

  • 表格类型选择TCP_TABLE_OWNER_MODULE_ALL(或TCP_TABLE_OWNER_PID_ALL,前者还包含模块路径信息),这个类型会返回所有状态的TCP条目,包括BOUND、LISTENING、ESTABLISHED等。
  • 地址族参数根据需要选AF_INET(IPv4)或AF_INET6(IPv6)。

关键结构体说明

调用成功后,你会得到MIB_TCPTABLE_OWNER_MODULE结构体(对应TCP_TABLE_OWNER_MODULE_ALL类型),其中每个条目是MIB_TCPROW_OWNER_MODULE,重点关注:

  • dwState:判断套接字状态,当值为MIB_TCP_STATE_BOUND时,就是你要找的已绑定未连接的套接字。
  • dwOwningPid:拥有该套接字的进程PID,方便你关联到目标应用程序。
  • lpModuleName/lpModulePath:可选的模块名称和路径,帮助你直接识别进程(如果用TCP_TABLE_OWNER_MODULE_ALL的话)。

简单代码示例

以下是一个简化的C++代码片段,演示如何获取所有BOUND状态的TCP套接字:

#include <windows.h>
#include <iphlpapi.h>
#include <iostream>
#include <ws2tcpip.h>

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

int main() {
    DWORD dwSize = 0;
    // 第一次调用获取所需缓冲区大小
    GetExtendedTcpTable(nullptr, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0);
    
    // 分配内存
    PMIB_TCPTABLE_OWNER_MODULE pTcpTable = (PMIB_TCPTABLE_OWNER_MODULE)malloc(dwSize);
    if (!pTcpTable) {
        std::cerr << "内存分配失败" << std::endl;
        return 1;
    }
    
    // 第二次调用获取实际数据
    if (GetExtendedTcpTable(pTcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) != NO_ERROR) {
        std::cerr << "获取TCP表格失败" << std::endl;
        free(pTcpTable);
        return 1;
    }
    
    // 遍历所有条目,筛选BOUND状态的套接字
    for (DWORD i = 0; i < pTcpTable->dwNumEntries; ++i) {
        MIB_TCPROW_OWNER_MODULE& row = pTcpTable->table[i];
        if (row.dwState == MIB_TCP_STATE_BOUND) {
            // 转换本地IP和端口
            char localIp[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, &row.dwLocalAddr, localIp, INET_ADDRSTRLEN);
            USHORT localPort = ntohs((USHORT)row.dwLocalPort);
            
            std::cout << "已绑定套接字: " << localIp << ":" << localPort 
                      << " | PID: " << row.dwOwningPid << std::endl;
        }
    }
    
    free(pTcpTable);
    return 0;
}

额外说明

  • 如果需要关联进程的.exe名称,可以通过dwOwningPid调用OpenProcess获取进程句柄,再用GetModuleFileNameEx获取进程路径,进而提取.exe名称。
  • 对于UDP套接字的已绑定状态,类似地可以使用GetExtendedUdpTable,指定UDP_TABLE_OWNER_MODULE_ALL类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:25:46