1. 程式人生 > >獲取本地計算機的網絡信息

獲取本地計算機的網絡信息

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;
}

  

獲取本地計算機的網絡信息