文章目录

  • GetExtendedTcpTable
    • 参数①PVOID pTcpTable
    • 参数②PDWORD pdwSize
    • 参数③BOOL bOrder
    • 参数④ULONG ulAf
    • 参数⑤TCP_TABLE_CLASS TableClass
    • 参数⑥ULONG Reserved
    • 返回值
    • 实例代码
  • GetOwnerModuleFromTcpEntry
    • 参数①
    • 参数②
    • 参数③
    • 参数④
    • 返回值

GetExtendedTcpTable

https://docs.microsoft.com/zh-cn/windows/win32/api/iphlpapi/nf-iphlpapi-getextendedtcptable
相当于执行
netstat -at

IPHLPAPI_DLL_LINKAGE DWORD GetExtendedTcpTable([out]     PVOID           pTcpTable,[in, out] PDWORD          pdwSize,[in]      BOOL            bOrder,[in]      ULONG           ulAf,[in]      TCP_TABLE_CLASS TableClass,[in]      ULONG           Reserved
);

参数①PVOID pTcpTable

指向查询结果结构体的指针,可以根据参数⑤设置不同的结构体
MIB_TCPTABLE
https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable

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

成员①为数组元素个数
成员②为MIB_TCPROW结构体数组,结构体定义如下

typedef struct _MIB_TCPROW_LH {union {DWORD         dwState;MIB_TCP_STATE State;};//TCP通信状态,例如:CLOSED,LISTEN,SYN_SENT等DWORD dwLocalAddr;DWORD dwLocalPort;DWORD dwRemoteAddr;DWORD dwRemotePort;
} MIB_TCPROW_LH, *PMIB_TCPROW_LH;

实例代码中用的是MIB_TCPTABLE_OWNER_MODULE,因为后面还需要获取每个通信进程对应的应用程序:
https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcptable_owner_module

typedef struct _MIB_TCPTABLE_OWNER_MODULE {DWORD                   dwNumEntries;MIB_TCPROW_OWNER_MODULE table[ANY_SIZE];
} MIB_TCPTABLE_OWNER_MODULE, *PMIB_TCPTABLE_OWNER_MODULE;

成员①为数组元素个数
成员②为MIB_TCPROW_OWNER_MODULE结构体数组,结构体定义如下:
https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcprow_owner_module

typedef struct _MIB_TCPROW_OWNER_MODULE {DWORD         dwState;//TCP通信状态,例如:CLOSED,LISTEN,SYN_SENT等DWORD         dwLocalAddr;//本地IP地址DWORD         dwLocalPort;//本地端口DWORD         dwRemoteAddr;//远程IP地址DWORD         dwRemotePort;//远程端口DWORD         dwOwningPid;//进程号LARGE_INTEGER liCreateTimestamp;//创建连接的时间戳ULONGLONG     OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];//进程模块信息
} MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE;

参数②PDWORD pdwSize

返回参数①的大小

参数③BOOL bOrder

是否升序排序,按以下信息进行排序:
1.本地IP地址
2.IPv6的本地域ID
3.本地端口号
4.远程IP地址
5.IPv6的远程域ID
6.远程端口号

参数④ULONG ulAf

IP地址簇类型,AF_INET对应IPv4,AF_INET6对应IPv6

参数⑤TCP_TABLE_CLASS TableClass

参数①类型,这里设置为TCP_TABLE_OWNER_MODULE_ALL
https://docs.microsoft.com/en-us/windows/win32/api/iprtrmib/ne-iprtrmib-tcp_table_class

typedef enum _TCP_TABLE_CLASS {TCP_TABLE_BASIC_LISTENER,TCP_TABLE_BASIC_CONNECTIONS,TCP_TABLE_BASIC_ALL,TCP_TABLE_OWNER_PID_LISTENER,TCP_TABLE_OWNER_PID_CONNECTIONS,TCP_TABLE_OWNER_PID_ALL,TCP_TABLE_OWNER_MODULE_LISTENER,TCP_TABLE_OWNER_MODULE_CONNECTIONS,TCP_TABLE_OWNER_MODULE_ALL
} TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;

从上面结构体成员名称带有不同关键字,具有不同含义,对于IPv4协议:

名称 含义
LISTENER 仅含接收端为listening状态的通信信息
CONNECTIONS 仅含终端为connected状态的通信信息
ALL 包含所有的通信信息
BASIC 包含基本的通信信息,通信状态、本地地址与端口,远程地址与端口,参数①对应结构体为MIB_TCPTABLE
OWNER_PID 除基本信息外还包含进程号,参数①对应结构体为MIB_TCPTABLE_OWNER_PID
OWNER_MODULE 除基本信息外还包含进程号与创建时间,参数①对应结构体为MIB_TCPTABLE_OWNER_MODULE

参数⑥ULONG Reserved

保留参数。

返回值

成功:NO_ERROR
失败:错误码,其中ERROR_INSUFFICIENT_BUFFER表示分配的内存不足,需要重新获取

实例代码

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <iphlpapi.h>//这个头文件位置不能和winsock2.h互换
#include <stdio.h>
#include<TCHAR.h>#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib,"ws2_32.lib")char Buf[0x1000];int main()
{WORD wVersionRequested = MAKEWORD(2, 2);//版本WSADATA wsaDATA;if (WSAStartup(wVersionRequested, &wsaDATA) != 0)//打开网络库{printf("打开网络库失败!\n");return -1;}PMIB_TCPTABLE_OWNER_MODULE pInfo = NULL;ULONG Length = 0;DWORD re = GetExtendedTcpTable(pInfo, &Length, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL,0);//第一次调用获取长度if (ERROR_INSUFFICIENT_BUFFER == re)//根据长度申请内存{pInfo = (PMIB_TCPTABLE_OWNER_MODULE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, Length);}re = GetExtendedTcpTable(pInfo, &Length, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL,0); //第二次调用获取信息if (NO_ERROR != re){printf("获取TCP通信信息失败,错误码为:%d\n", re);HeapFree(GetProcessHeap(), 0, (pInfo));return -1;}for (DWORD i = 0; i < pInfo->dwNumEntries; i++){PTCPIP_OWNER_MODULE_BASIC_INFO pInfo_app = (PTCPIP_OWNER_MODULE_BASIC_INFO)Buf;DWORD Length = 0x1000; re = GetOwnerModuleFromTcpEntry(&pInfo->table[i], TCPIP_OWNER_MODULE_INFO_BASIC, pInfo_app, &Length);//获取通信对应的应用程序信息_tprintf(L"%d. %s\n\t%s\n", i, pInfo_app->pModulePath, pInfo_app->pModuleName);//输出序号、程序路径、程序名称in_addr Local, Remote;Local.S_un.S_addr = pInfo->table[i].dwLocalAddr; Remote.S_un.S_addr = pInfo->table[i].dwRemoteAddr; printf("\t%s:%d\t", inet_ntoa(Local), ntohs(pInfo->table[i].dwLocalPort)); //输出本地IP和端口printf("\n\t%s:%d\n", inet_ntoa(Remote), ntohs(pInfo->table[i].dwRemotePort));//输出远程IP和端口switch (pInfo->table[i].dwState) //根据状态码打印对应状态{case MIB_TCP_STATE_CLOSED:printf("\tCLOSED\n");break;case MIB_TCP_STATE_LISTEN:printf("\tLISTEN\n");break;case MIB_TCP_STATE_SYN_SENT:printf("\tSYN-SENT\n");break;case MIB_TCP_STATE_SYN_RCVD:printf("\tSYN-RECEIVED\n");break;case MIB_TCP_STATE_ESTAB:printf("\tESTABLISHED\n");break;case MIB_TCP_STATE_FIN_WAIT1:printf("\tFIN-WAIT-1\n");break;case MIB_TCP_STATE_FIN_WAIT2:printf("\tFIN-WAIT-2 \n");break;case MIB_TCP_STATE_CLOSE_WAIT:printf("\tCLOSE-WAIT\n");break;case MIB_TCP_STATE_CLOSING:printf("\tCLOSING\n");break;case MIB_TCP_STATE_LAST_ACK:printf("\tLAST-ACK\n");break;case MIB_TCP_STATE_TIME_WAIT:printf("\tTIME-WAIT\n");break;case MIB_TCP_STATE_DELETE_TCB:printf("\tDELETE-TCB\n");break;default:printf("\tUNKNOWN dwState value: %d\n", pInfo->table[i].dwState);break;}}if (pInfo != NULL) {HeapFree(GetProcessHeap(), 0, (pInfo));pInfo = NULL;}WSACleanup(); getchar(); return 0;
}

运行结果如下图:

除了TCP外,还有对应获取UDP通信信息的函数,相当于执行netstat -au
https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getextendedudptable

IPHLPAPI_DLL_LINKAGE DWORD GetExtendedUdpTable([out]     PVOID           pUdpTable,[in, out] PDWORD          pdwSize,[in]      BOOL            bOrder,[in]      ULONG           ulAf,[in]      UDP_TABLE_CLASS TableClass,[in]      ULONG           Reserved
);

使用方法与GetExtendedTcpTable一样,仅在参数的取值上有一些不一样,这里不再赘述。
注意:这里涉及到的结构体一层套一层,初学者很难进行分辨,记忆要点在于将通信信息最后看做一张表格:

函数GetExtendedTcpTable获取的就是这个表格(Table)大结构体,表格是由多行(Row)组成,把每一行看做一个元素,那么表格就相当于由行数组组成,表格中每一行Row也就是小结构体每个对应一条TCP通信信息(本地IP和端口、远程IP和端口、状态等。)

GetOwnerModuleFromTcpEntry

https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getownermodulefromtcpentry

IPHLPAPI_DLL_LINKAGE DWORD GetOwnerModuleFromTcpEntry([in]      PMIB_TCPROW_OWNER_MODULE      pTcpEntry,[in]      TCPIP_OWNER_MODULE_INFO_CLASS Class,[out]     PVOID                         pBuffer,[in, out] PDWORD                        pdwSize
);

参数①

就是表格中的行数组元素
MIB_TCPROW_OWNER_MODULE结构体数组,结构体定义如下:
https://docs.microsoft.com/en-us/windows/win32/api/tcpmib/ns-tcpmib-mib_tcprow_owner_module

typedef struct _MIB_TCPROW_OWNER_MODULE {DWORD         dwState;//TCP通信状态,例如:CLOSED,LISTEN,SYN_SENT等DWORD         dwLocalAddr;//本地IP地址DWORD         dwLocalPort;//本地端口DWORD         dwRemoteAddr;//远程IP地址DWORD         dwRemotePort;//远程端口DWORD         dwOwningPid;//进程号LARGE_INTEGER liCreateTimestamp;//创建连接的时间戳ULONGLONG     OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];//进程模块信息
} MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE;

参数②

TCPIP_OWNER_MODULE_INFO_CLASS枚举类型

参数③

TCPIP_OWNER_MODULE_BASIC_INFO结构体
https://docs.microsoft.com/en-us/windows/win32/api/iprtrmib/ns-iprtrmib-tcpip_owner_module_basic_info

typedef struct _TCPIP_OWNER_MODULE_BASIC_INFO {PWCHAR pModuleName;PWCHAR pModulePath;
} TCPIP_OWNER_MODULE_BASIC_INFO, *PTCPIP_OWNER_MODULE_BASIC_INFO;

传址调用,因此这里两个成员都必须为NULL
成员①:应用程序路径+名称
成员②:应用程序名称
由于应用程序路径里面包含特殊符号,输出的时候用_tprintf。

参数④

参数③的大小

返回值

成功:NO_ERROR
失败:错误码,ERROR_INSUFFICIENT_BUFFER为参数①大小不足的错误,需要重新申请内存。

获取本地TCP通信信息相关推荐

  1. linux c 通过套接字获取本地远程地址信息 getsockname getpeername 简介

    getsockname 函数用于获取与某个套接字关联的本地协议地址  getpeername 函数用于获取与某个套接字关联的外地协议地址 定义如下: #include<sys/socket.h& ...

  2. 通过百度地图实现定位并获取本地当日天气信息

    首先,通过之前用过的百度地图,实现定位功能:首先去百度开放云申请密钥,这里就不说明申请过程了,不懂得可以百度一下. 申请完密钥后,需要去声明Activity的地方添加上下面的语句: <meta- ...

  3. 获取本地IP地址信息,请求地址,请求的操作系统信息 ,浏览器信息

    程序运行效果图,如果这种有你需要的信息,不妨随着小编一起看下去吧! (1)接口 在浏览器上访问 localhost:8089/test/cs @RequestMapping("/cs&quo ...

  4. wmi获取硬件信息c语言,通过 WMI来获取本地计算机软件硬件信息

    一网打尽 介绍及款工具  WMITools和WMICodeCreator 生成.net或vbs代码来操作WMI的. 您想需要怎么调用都可以了.具体怎么下,google或bing下吧. 相关脚本 'On ...

  5. 关于IOS获取本地通讯录信息(包含iOS9.0前后)

    在ios开发当中,获取用户本地的通讯录功能愈加频繁的出现,七两自己也在自己公司的项目当中遇到的获取本地的通讯录信息的功能(俗称"种子用户功能",太可怕了).对此七两总结了自己使用本 ...

  6. IE 获取 本地 Mac地址

    文章目录 需求 解决 总结 需求 在django里面扩展用户信息,添加mac地址 获取本地Mac地址信息,并一起post到服务器 在服务器对Mac地址进行校验 解决 django里面扩展用户信息可以这 ...

  7. java解析tcp报文_JAVA语言TCP通信和JDBC示例(AIS信息解析)

    JAVA实现AIS信息的接受,解析和存储 船舶自动识别系统(Automatic Identification System, 简称AIS)是一种新型的助航设备.AIS基本功能是:将本船和他船的精确船位 ...

  8. 浏览器调用exe并从中获取内容的通用解决方案之浏览器和本地exe通信篇

    除了IE支持OCX可以直接在浏览器内部,其他所有现代浏览器都不支持内嵌exe执行并交互返回内容了 采用的是本地HttpListener监听端口,然后前端轮询jsonp的方式实现浏览器和本地exe通信, ...

  9. QT获取本地网络信息

    QT获取本地网络信息 开发工具与关键技术:QtCreator.C++ 作者:何任贤 撰写时间:2020年06月10日 获取本机网络信息要在工程文件(.Pro)加上 QT += network 然后就是 ...

最新文章

  1. Fiddler小技巧-测试上传文件接口多参数并传情况
  2. Error:could not open'C:\Porogram Files\Java\jrelib\j386\jvm.cfg'
  3. 单应性矩阵求解函数findHomography()
  4. SQLite安装、编译与应用
  5. Tensorflow LSTM时间序列预测的尝试
  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载...
  7. 昆士兰科技大学计算机专业,昆士兰科技大学QUT计算机科学Computer Science专业排名第101-125位(2021年THE世界大学商科排名)...
  8. 接口实例(C#,IShape)【C#】
  9. go出现missing go.sum entry for module providing package 错误
  10. [ES6] 细化ES6之 -- 键值对集合
  11. android删除wifi配置,[RK3288][Android6.0] WiFi之无线网络配置的忘记(移除)过程
  12. 实现自我隐藏 CPU 利用率的最佳方法,不妨一试!
  13. 用python输出200以内的素数_Python练习题 008:打印101-200之间的所有素数
  14. net-snmp的定制编译
  15. 《麦肯锡方法》读书笔记16
  16. UE4 C++如何关闭进程?
  17. Altium designer原理图检查(编译检查)
  18. android 手机内存uri_[Android]Android数据的四种存储方式 - Ron Ngai - 博客园
  19. 职场故事让你如梦初醒
  20. IOS使用Charts

热门文章

  1. 0319 预习笔记和直播笔记
  2. 【笔记】pth、pt、pkl的区别:pt 常做数据集的数据存储形式
  3. 定义一个数组,获取数组中的最大值和最小值
  4. bxslider 旋转
  5. 女人都需要学会的四种气质
  6. 若依项目springcloud启动
  7. chatGPT 使用场景
  8. 服务器的地址信息,服务器地址信息
  9. matlab对波士顿房价进行分析及预测
  10. 只允许匿名用户下载的ftp