獲取本地計算機的網絡信息
阿新 • • 發佈:2017-11-06
mixed comm windows 數據大小 一個 等待 ast 聲明 ffi
Windows網絡編程第六章探測網絡中的在線設備
實驗:獲取本地計算機的網絡信息
實驗分析:主要練習對GetAdaptersInfo()、GetNetworkParams()、GetInterfaceInfo()、GetIPAddrTable()等API函數的運用,實驗中需要註意的是需要兩次調用該函數,第一次返回本機要調查信息的數量,第二次調用顯示具體信息。
GetInfo.h
void pAdapter(); void Network(); void NumberOfInterfaces(); int GetIpAddr();
GetInfo.cpp
//********************聲明頭文件**************************** #include<iostream> #include<WinSock2.h> #include<IPHlpApi.h> #include<stdio.h> #pragma comment(lib,"ws2_32.lib") using namespace std; #pragma comment(lib,"IPHLPAPI.lib") //****************一、獲取本地網絡適配器信息*************** void pAdapter() { //聲明變量 //指定獲取到的網絡信息結構體鏈表的指針 IP_ADAPTER_INFO *pAdapterInfo; //保存獲取到的網絡信息結構體鏈表的長度 ULONG ulOutBufLen; //返回調用編碼 DWORD dwRetVal; //在輪循所有網絡適配器信息時使用的單個結構體變量 PIP_ADAPTER_INFO pAdapter; //*******************獲取本地網絡適配器信息*************** //為pAdapterInfo分配空間 pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); ulOutBufLen = sizeof(IP_ADAPTER_INFO); //第一次調用GetAdaptersInfo(),獲取返回結果的大小保存到ulOutBufLen中 if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); //pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); } cout << pAdapterInfo->AddressLength; //第二次調用GetAdaptersInfo(),獲取本地網絡信息保存到結構體pAdapterInfo中 //dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen); if ((dwRetVal=GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS) { cout << "GetAdaptersInfo Error!"<< dwRetVal << endl; } //***********************顯示本地網絡適配器信息****************** pAdapter = pAdapterInfo; while (pAdapter) { cout << "網絡適配器名:" << pAdapter->AdapterName<<endl; cout << "網絡適配器描述:" << pAdapter->Description << endl; cout << "MAC地址: \t" ; //處理MAC地址 for (int i = 0; i < pAdapter->AddressLength; i++) { if (i == (pAdapter->AddressLength - 1)) printf("%.2X\n", (int)pAdapter->Address[i]); else printf("%.2X-", (int)pAdapter->Address[i]); } cout << "IP地址:\t" << pAdapter->IpAddressList.IpAddress.String<<endl; cout << "子網掩碼:\t" << pAdapter->IpAddressList.IpMask.String<<endl; cout << "網關:\t" << pAdapter->GatewayList.IpAddress.String<<endl; if (pAdapter->DhcpEnabled) { cout << "啟用DHCP:是"<<endl; cout << "DHCP服務器:" << pAdapter->DhcpServer.IpAddress.String; } else { cout << "啟用DHCP:否" << endl; } cout << endl; //處理下一個網絡適配器 pAdapter = pAdapter->Next; } //***************************釋放資源******************** if (pAdapterInfo) free(pAdapterInfo); //*************************暫停程序,等待用戶響應*************** printf("\n\n"); //system("pause"); } //*********************二、獲取本地主機名、域名、DNS服務器信息**************** void Network() { //********************2.聲明變量**************************** //定義保存本地計算機網絡參數信息的結構體指針 FIXED_INFO * FixedInfo; //保存獲取到的本地計算機網絡參數信息結構體鏈表的長度 ULONG ulOutBufLen; //調用GetNetworkParams()返回值 DWORD dwRetVal; //保存所有DNS服務器的IP地址列表 IP_ADDR_STRING* pIPAddr; //******************3.獲取本地網絡參數信息*************************** //為FixedInfo結構體分配內存空間 FixedInfo = (FIXED_INFO*)GlobalAlloc(GPTR, sizeof(FIXED_INFO)); //初始化ulOutBuflen變量值 ulOutBufLen = sizeof(FIXED_INFO); //第一次調用GetNetworkParams()函數,獲取返回數據的大小到ulOutBufLen中 if (ERROR_BUFFER_OVERFLOW == GetNetworkParams(FixedInfo, &ulOutBufLen)){ GlobalFree(FixedInfo); FixedInfo = (FIXED_INFO*)GlobalAlloc(GPTR, ulOutBufLen); } //第2次調用GetNetworkParams()函數,以前面獲取的ulOutBufLen作為參數 if (dwRetVal = GetNetworkParams(FixedInfo, &ulOutBufLen) != ERROR_SUCCESS){ cout << "調用GetNetworkParams()函數失敗!返回值:" << dwRetVal << endl; } else { cout << "主機名:" << FixedInfo->HostName << endl; cout << "域名:" << FixedInfo->DomainName << endl; cout << "網絡信息:" << endl; char* NodeType; switch (FixedInfo->NodeType) { case BROADCAST_NODETYPE: NodeType = "Broadcase Node"; break; case PEER_TO_PEER_NODETYPE: NodeType = "Peer to Peer Node"; break; case MIXED_NODETYPE: NodeType = "Mixed Node"; break; case HYBRID_NODETYPE: NodeType = "Hybrid Node"; break; default: NodeType = "Unknow Node"; break; } cout << "節點類型:" << FixedInfo->NodeType << NodeType << endl; printf("是否啟用路由功能:%s\n", (FixedInfo->EnableRouting != 0) ? "是" : "否"); printf("是否啟用ARP代理功能:%s\n", (FixedInfo->EnableProxy != 0) ? "是" : "否"); printf("是否啟用DNS服務器:%s\n", (FixedInfo->EnableDns != 0) ? "是" : "否"); printf("\n服務器列表\n"); printf("%s\n", FixedInfo->DnsServerList.IpAddress.String); pIPAddr = FixedInfo->DnsServerList.Next; while (pIPAddr){ printf("\t%s\n", pIPAddr->IpAddress.String); pIPAddr = pIPAddr->Next; } } printf("\n"); } //*********************獲取本地計算機網絡接口的基本信息************************ void NumberOfInterfaces() { //保存網絡接口信息的結構體指針 PIP_INTERFACE_INFO pInfo=NULL; //保存獲取數據的長度 ULONG ulOutBufLen = 0; //返回結果 DWORD dwRetVal=0; int iReturn = 0; //第一次調用GetInterfaceInfo,獲取數據大小,保存到ulOutBufLen變量中 dwRetVal = GetInterfaceInfo(NULL, &ulOutBufLen); if (dwRetVal == ERROR_INSUFFICIENT_BUFFER){ pInfo = (IP_INTERFACE_INFO *)malloc(ulOutBufLen); if (pInfo == NULL){ printf("無法分配GetInterfaceInfo函數需要的內存空間。\n"); } } //第二次調用GetInterfaceInfo,獲取需要的實際數據 dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen); if (dwRetVal == NO_ERROR){ printf("網絡適配器數量:%ld\n\n", pInfo->NumAdapters); for (int i = 0; i < (int)pInfo->NumAdapters; i++) { printf("網絡適配器索引[%d]:%ld\n", i,pInfo->Adapter[i].Index); printf("網絡適配器名稱[%d]:%ws\n\n", i, pInfo->Adapter[i].Name);//? } iReturn = 0; } else if (dwRetVal == ERROR_NO_DATA) { printf("本地計算機上沒有支持IPV4的網絡適配器。\n"); iReturn = 1; } else{ printf("GetInterfaceInfo調用失敗:%d\n", dwRetVal); } //釋放內存空間 free(pInfo); } //*****************獲取本地計算機IP地址表********************** //分配內存空間 #define MALLOC(x) HeapAlloc(GetProcessHeap(),0,(x)) //釋放內存空間 #define FREE(x) HeapFree(GetProcessHeap(),0,(x)) int GetIpAddr() { //網絡接口與IP地址映射表 PMIB_IPADDRTABLE pIPAddrTable; //獲取數據的大小 DWORD dwSize = 0; //調用GetIPAddrTable()函數的返回值 DWORD dwRetval = 0; //保存IP地址的結構體 IN_ADDR IPAddr; //用於獲取錯誤信息 LPVOID lpMsgBuf; //IN_ADDR的定義如下: typedef struct in_addr IN_ADDR; //分配內存空間 pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(sizeof(MIB_IPADDRTABLE)); //第一次調用GetIPAddrTable()函數,獲取數據的大小到dwSize if (pIPAddrTable) { if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER){ FREE(pIPAddrTable); pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(dwSize); } if (pIPAddrTable == NULL) { printf("GetIpAddrTable()函數內存分配失敗\n"); exit(1); } } //第2次調用GetIPAddrTable()函數,獲取實際數據 if ((dwRetval = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR){ printf("GetIpAddrTable()調用失敗:%d\n", dwRetval); if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetval, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL)) { printf("\t錯誤信息:%s", lpMsgBuf); LocalFree(lpMsgBuf); } exit(1); } //顯示獲取到的IP地址信息 printf("\t記錄數量:%ld\n", pIPAddrTable->dwNumEntries); for (int i = 0; i < (int)pIPAddrTable->dwNumEntries; i++) { printf("\n\t接口序號[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); IPAddr.S_un.S_addr = (u_long)pIPAddrTable->table[i].dwAddr; printf("\tIP地址[%d]: \t%s\n", i, inet_ntoa(IPAddr)); IPAddr.S_un.S_addr = (u_long)pIPAddrTable->table[i].dwMask; printf("\t子網掩碼[%d]: \t%s\n", i, inet_ntoa(IPAddr)); IPAddr.S_un.S_addr = (u_long)pIPAddrTable->table[i].dwBCastAddr; printf("\t廣播地址[%d]:\t%s(%ld%)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); printf("\t重組報文最大數量[%d]:\t %ld\n", i, pIPAddrTable->table[i].dwReasmSize); printf("\t類型和狀態:[%d]:", i); if (pIPAddrTable->table[i].wType & MIB_IPADDR_PRIMARY) printf("\t主IP地址"); if (pIPAddrTable->table[i].wType & MIB_IPADDR_DYNAMIC) printf("\t動態IP地址"); if (pIPAddrTable->table[i].wType & MIB_IPADDR_DISCONNECTED) printf("\t斷開連接的接口對應的IP地址"); if (pIPAddrTable->table[i].wType & MIB_IPADDR_DELETED) printf("\t刪除的IP地址"); if (pIPAddrTable->table[i].wType & MIB_IPADDR_TRANSIENT) printf("\t臨時地址"); printf("\n"); } //釋放內存空間 if (pIPAddrTable){ FREE(pIPAddrTable); pIPAddrTable = NULL; } return 0; }
GetNetworkParams.cpp
//********************1.聲明頭文件**************************** #include<iostream> #include<string> //#include"stdafx.h" #include"GetInfo.h" #include<WinSock2.h> #include<IPHlpApi.h> #include<stdio.h> #pragma comment(lib,"IPHLPAPI.lib") using namespace std; int main() { while (true) { cout << "請選擇您要進行的操作:" << endl; cout << "1.獲取本地網絡適配器信息" << endl; cout << "2.獲取本地主機名、域名、DNS服務器信息" << endl; cout << "3.獲取本地計算機網絡接口的基本信息" << endl; cout << "4.獲取本地計算機IP地址表" << endl; cout << "其他鍵退出" << endl; string select = ""; cin >> select; if (select == "1") { pAdapter();//獲取本地網絡適配器信息 } else if (select == "2") { Network();//獲取本地主機名、域名、DNS服務器信息 } else if (select == "3") { NumberOfInterfaces();//獲取本地計算機網絡接口的基本信息 } else if (select == "4") GetIpAddr();//獲取本地計算機IP地址表 else { cout << "已退出" << endl; break; } } return 0; }
獲取本地計算機的網絡信息