闲的蛋疼,写的小程序,首先感谢Sakura的帮助~
参考文献地址:GetTcpTable2的MSDN说明,其中的例子很详细,GetExtendedXXXTable虽然函数调用方式不一样但拿到的连接信息调用方式是一样的。
主要使用的API: GetTcpTable2和GetExtendedUdpTable(GetExtendedTcpTable)
#include
#include
#include
#include
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
typedef unsigned int uint;
typedef QMultimap INFOMAP;
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
bool GetProcessPort(INFOMAP& portmap)
{
portmap.clear();
PMIB_TCPTABLE2 pTcpTable;
ULONG ulSize = 0;
DWORD dwRetVal = 0;
char szLocalAddr[128];
char szRemoteAddr[128];
struct in_addr IpAddr;
int i;
pTcpTable = (MIB_TCPTABLE2 *) MALLOC(sizeof (MIB_TCPTABLE2));
if (pTcpTable == NULL) {
status=("Error allocating memoryn");
return false;
}
ulSize = sizeof (MIB_TCPTABLE);
// Make an initial call to GetTcpTable2 to
// get the necessary size into the ulSize variable
if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) ==
ERROR_INSUFFICIENT_BUFFER) {
FREE(pTcpTable);
pTcpTable = (MIB_TCPTABLE2 *) MALLOC(ulSize);
if (pTcpTable == NULL) {
status=("Error allocating memoryn");
return false;
}
}
// Make a second call to GetTcpTable2 to get
// the actual data we require
if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR) {
printf("tNumber of entries: %dn", (int) pTcpTable->dwNumEntries);
for (i = 0; i < (int) pTcpTable->dwNumEntries; i++) {
uint portnum = ntohs((u_short)pTcpTable->table[i].dwLocalPort);
uint pid = pTcpTable->table[i].dwOwningPid;
portmap.insert(portnum,pid);
}
} else {
status=QString("tGetTcpTable2 failed with %1n").arg(dwRetVal);
FREE(pTcpTable);
return false;
}
if (pTcpTable != NULL) {
FREE(pTcpTable);
pTcpTable = NULL;
}
MIB_UDPTABLE_OWNER_PID* pUdpTable;
pUdpTable = (MIB_UDPTABLE_OWNER_PID *) MALLOC(sizeof (MIB_UDPTABLE_OWNER_PID));
if (pUdpTable == NULL) {
status=("Error allocating memoryn");
return false;
}
ulSize = sizeof (MIB_UDPTABLE_OWNER_PID);
if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, false,AF_INET,UDP_TABLE_OWNER_PID,0)) ==
ERROR_INSUFFICIENT_BUFFER) {
FREE(pUdpTable);
pUdpTable = (MIB_UDPTABLE_OWNER_PID *) MALLOC(ulSize);
if (pUdpTable == NULL) {
status=("Error allocating memoryn");
return false;
}
}
if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, false,AF_INET,UDP_TABLE_OWNER_PID,0)) == NO_ERROR) {
printf("tNumber of entries: %dn", (int) pUdpTable->dwNumEntries);
for (i = 0; i < (int) pUdpTable->dwNumEntries; i++) {
uint portnum = ntohs((u_short)pUdpTable->table[i].dwLocalPort);
uint pid = pUdpTable->table[i].dwOwningPid;
portmap.insert(portnum,pid);
}
} else {
status=QString("tGetTcpTable2 failed with %1n").arg(dwRetVal);
FREE(pUdpTable);
return false;
}
if (pUdpTable != NULL) {
FREE(pUdpTable);
pUdpTable = NULL;
}
return true;
}
最终的进程pid<->端口信息存储在portmap这个multimap里面。(我用的QT做GUI,当然QMultimap可以换成其他任何map)
关于GetExtendedXXXTable需要注意的是,这个函数有不同的table参数可以传入,根据你想获得什么样的扩展信息,其他的和GetTcpTable2基本一致。