本地计算机网络信息的获取

本地计算机网络信息的获取

 

一。这次的程序,主要实现下面功能:

功能的实现都非常简单,有五种函数可以直接调用:

1.用于获取本地网络适配器信息的函数:

     DWORD GetAdaptersInfo( PIP_ADAPTER_INFO pAdapterInfo,  PULONG pOutBufLen );

2.用于获取本地主机名、域名和DNS服务器信息的函数:

     DWORD GetNetworkParamsInfo(PFIXED_INFO pFixedInfo, PULONG pOutBufLen );

3.用于获取本地计算机网络接口数量的函数

     DWORD GetNumberOfInterfaces(PDWORD pdwNumIf);

4.用于获取本地主机名、域名和DNS服务器信息的函数

     DWORD GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable,         PULONG dwOutBufLen );

5.获取本地计算机IP地址表的函数

     DWORD GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder );

 

二。下面是程序执行效果图

 

 

三。源代码

// getNativeComputerNetInformation.cpp

#include <stdio.h>
#include <WinSock2.h>
#include <iphlpapi.h>

#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "ws2_32.lib")

int main()
{
// 各类函数声明
	int GetAdaptersInfoFunction();			// 获取本地网络适配器信息的函数
	int GetNetworkParamsFunction();			// 获取本地主机名、域名和DNS服务器信息
	int GetInterfacesFunction();	        // 获取本地计算机网络接口的基本信息
	int GetIpAddrTableFunction();			// 获取本地计算机的IP地址


// 各类函数调用
	char choice;
	do{
		system("cls");
		printf("1.获取本地网络适配器信息的函数 GetAdaptersInfoFunction();\n");
		printf("2.获取本地主机名、域名和DNS服务器信息 GetNetworkParamsFunction();\n");
		printf("3.获取本地计算机网络接口的基本信息 GetInterfacesFunction();\n");
		printf("4.获取本地计算机的IP地址 GetIpAddrTableFunction();\n");
		printf("0.退出程序\n");
		printf("请输入需要调用的函数:");
		scanf("%c", &choice);
		printf("\n\n");
		switch(choice){
			case '0': break;
			case '1':	GetAdaptersInfoFunction(); break;
			case '2': GetNetworkParamsFunction(); break;
			case '3': GetInterfacesFunction(); break;
			case '4': GetIpAddrTableFunction(); break;
			default: break;
		}
	}while('0' != choice);

	return 0;
}
	

/**
 * 用于获取本地网络适配器信息的函数:
 * DWORD GetAdaptersInfo(
 *   _in PIP_ADAPTER_INFO pAdapterInfo;    // 结构体保存获取到的网络适配器的信息
 *   _out PULONG pOutBufLen                // 保存pAdapterInfo缓冲区的大小
 * );
 *
 * 网络适配器的信息的结构体:
 * typedef struct _IP_ADAPTER_INFO {
 *   struct _IP_ADAPTER_INFO* Next;                 // 指定网络适配器链表中的下一个网络适配器
 *   DWORD ComboIndex;                              // 预留变量
 *   char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; // 网络适配器的名称
 *   char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];  // 网络适配器的描述信息
 *   UINT AddressLength;			                // 网络适配器MAC的长度
 *   BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];      // 网络适配器的MAC地址
 *   DWORD Index;                                   // 网络适配器索引(重启计算机会改变的值)
 *   UINT Type;                                     // 网络适配器的类型
 *   UINT DhcpEnabled;                              // 指定该网络适配器上是否启用了DHCP
 *   PIP_ADDR_STRING CurrentIpAddress;              // 预留变量
 *   IP_ADDR_STRING IpAddressList;                  // 与此网络适配器上相关联的IP地址列表
 *   IP_ADDR_STRING GatewayList;                    // 该网络适配器上定义的IP地址的默认网关
 *   IP_ADDR_STRING DhcpServer;                     // 该网络适配器上定义的DHCP服务器的IP地址
 *   BOOL HaveWins;                                 // 标明该网络适配器是否启用了WINS
 *   IP_ADDR_STRING PrimaryWinsServer;              // 主WIN服务器的IP地址
 *   IP_ADDR_STRING SecondaryWinsServer;            // 从WINS服务器的IP地址
 *   time_t LeaseObtained;                          // 当前的DHCP租借获取的时间,只有在启用DHCP时生效
 *   time_t LeaseExpires;                           // 当前的DHCP租借失败的时间,只有在启用DHCP时生效
 * } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
 **/

int GetAdaptersInfoFunction()	// 获取本地网络适配器信息的函数
{
// 变量声明 
	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()函数
	// 第1次调用GetAdaptersInfo(), 获取返回结果的大小保存到ulOutBufLen中
	// 因为网络信息结构体链表的默认长度是不知道的
	if(ERROR_SUCCESS != GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) ){
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
	}
	// 第2次调用GetAdaptersInfo(), 获取本地网络信息保存到结构体pAdapterInfo中
	if(ERROR_SUCCESS != (dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen))){
		printf("GetAdaptersInfo Error! &d\n", dwRetVal);
		exit(1);
	}

// 显示本地网络适配器信息,从pAdapterInfo获取并显示本地网络信息
	pAdapter = pAdapterInfo;
	while(pAdapter){
		printf("网络适配器名: \t\t%s\n", pAdapter->AdapterName);
		printf("网络适配器描述: \t%s\n\n", pAdapter->Description);
		printf("MAC地址:\t\t");
		// 处理MAC地址
		for(unsigned 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]);
			}
		}
		printf("IP地址: \t\t%s\n", pAdapter->IpAddressList.IpAddress.String);
		printf("子网掩码: \t\t%s\n", pAdapter->IpAddressList.IpMask.String);
		printf("网关: \t\t\t%s\n", pAdapter->GatewayList.IpAddress.String);
		printf("---------------\n");
		if(pAdapter -> DhcpEnabled){ // 指定该网络适配器上是否启用了DHCP
			printf("启用DHCP: \t\t是\n");
			printf("DHCP服务器: \t\t%s\n", pAdapter->DhcpServer.IpAddress.String);
		}
		else{
			printf("启用DHCP: \t\t否\n");
		}
		// 处理下一个网络适配器
		pAdapter = pAdapter -> Next;
		if(pAdapter){
			printf("\n\n**************************************************************\n");
		}
	}

// 释放资源
	if(pAdapterInfo){
		free(pAdapterInfo);
	}
   
	printf("\n\n");
	system("pause");
	return 0;
}

/**
 * 用于获取本地主机名、域名和DNS服务器信息的函数:
 * DWORD GetNetworkParamsInfo(
 *   _out PFIXED_INFO pFixedInfo;    // 使用FIXED_INFO结构体保存获取到的本地网络参数的信息
 *   _in PULONG pOutBufLen           // 保存pFixedInfo缓冲区的大小
 * );
 *
 * 保存本地主机名、域名和DNS服务器信息的结构体:
 * typedef struct { 
 *  char HostName[MAX_HOSTNAME_LEN + 4];      // 本地计算机的主机名
 *  char DomainName[MAX_DOMAIN_NAME_LEN + 4]; // 本地计算机注册到域的名称
 *  PIP_ADDR_STRING CurrentDnsServer;         // 预留变量
 *  IP_ADDR_STRING DnsServerList;             // 指定本地计算机上定义的DNS服务器列表
 *  UINT NodeType;                            // 本地计算机的节点类型
 *  char ScopeId[MAX_SCOPE_ID_LEN + 4];       // DHCP域名
 *  UINT EnableRouting;                       // 指定本地计算机是否启用了路由的功能
 *  UINT EnableProxy;                         // 指定本地计算机是否为ARP代理
 *  UINT EnableDns;                           // 指定本地计算机是否启用了DNS
 * } FIXED_INFO, *PFIXED_INFO;
 **/

int GetNetworkParamsFunction() // 获取本地主机名、域名和DNS服务器信息
{		
// 声明变量
	FIXED_INFO * FixedInfo;		// 定义保存本地计算机网络参数信息的结构体指针
	ULONG    ulOutBufLen;		// 保存获取到的本地计算机网络参数信息结构体链表的长度
	DWORD    dwRetVal;			// 调用GetNetworkParams()函数的返回值
    IP_ADDR_STRING * pIPAddr;	// 保存所有DNS服务器的IP地址列表

// 获取信息
	
	FixedInfo = (FIXED_INFO *) GlobalAlloc( GPTR, sizeof( FIXED_INFO ) );	// 为FixedInfo结构体分配内存空间
    ulOutBufLen = sizeof( FIXED_INFO );			// 初始化ulOutBufLen变量值
    
	// 第1次调用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) {
        printf( "调用GetNetworkParams()函数失败。返回值: %08x\n", dwRetVal );
    }
    else {
		printf( "主机名: %s\n", FixedInfo->HostName );
		printf( "域名: %s\n", FixedInfo->DomainName );
		printf("\n==========网络信息==========\n"); 

		 // 生成节点类型字符串
     	 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 = "Unknown Node";  break; 
         } 

		printf("节点类型...................:%d - %s\n", FixedInfo->NodeType, NodeType); 
        printf("是否启用路由功能...........:%s\n", (FixedInfo->EnableRouting != 0) ? "是" : "否"); 
        printf("是否启用ARP代理功能........:%s\n", (FixedInfo->EnableProxy != 0) ? "是" : "否"); 
        printf("是否启用DNS服务器..........:%s\n", (FixedInfo->EnableDns != 0) ? "是" : "否"); 

		printf( "\nDNS服务器列表:\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");
	system("pause");   
	return 0;
}

/**
 * 用于获取本地计算机网络接口数量的函数
 * DWORD GetNumberOfInterfaces(
 *   _out PDWORD pdwNumIf
 * );
 *
 * 用于获取本地主机名、域名和DNS服务器信息的函数
 * DWORD GetInterfaceInfo(
 *  _out PIP_INTERFACE_INFO pIfTable,	// 接受本地计算机网络接口基本信息的结构体IP_INTERFACE_INFO
 *  _inout PULONG dwOutBufLen           // 接到数据的大小
 * );
 *
 * 用于保存计算机网络接口信息的结构体
 * typedfe struct _IP_ADAPTER_INDEX_MAP{
 *  ULONG Index;                     // 网络适配器索引号
 *  WCHAR Name[MAX_ADAPTER_NAME];	// 网络适配器名称
 * }IP_INTERFACE_INDEX_MAP, *PIP_ADAPTER_INDEX_MAP; 
 **/

// 分配内存空间
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) 
// 释放内存空间
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int GetInterfacesFunction()	// 获取本地计算机网络接口的基本信息
{
// 获取网络接口的数量
	DWORD dwNumIf;		// 用于获取接口数量
	DWORD  dwRetVal;	// 返回值
	if(dwRetVal = GetNumberOfInterfaces(&dwNumIf) == NO_ERROR){
		printf("本地网络接口数量为: %d\n", dwNumIf);
	}
	else{
		printf("调用GetNumberOfInterfaces()函数时出现错误。\n");
	}

// 获取网络接口的基本信息
	PIP_INTERFACE_INFO pInfo;	// 保存网络接口信息的结构体指针
    ULONG ulOutBufLen = 0;		// 保存获取数据的长度
    int iReturn = 1;			// 本函数的返回结果

	// 第1次调用 GetInterfaceInfo,获取数据大小,保存到ulOutBufLen变量中
    dwRetVal = GetInterfaceInfo(NULL, &ulOutBufLen);
    if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
        pInfo = (IP_INTERFACE_INFO *) MALLOC(ulOutBufLen);
        if (pInfo == NULL) {
            printf("无法分配GetInterfaceInfo函数需要的内存空间。\n");
            return 1;
        }
    }
    // 第2次调用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 = 0;
    } else {
        printf("GetInterfaceInfo调用失败: %d\n", dwRetVal);
        iReturn = 1;
    }
	
    FREE(pInfo);	// 释放内存空间
    system("pause");
    return (iReturn);
}



/** 
 * 获取本地计算机IP地址表的函数
 * DWORD GetIpAddrTable(
 *   _out PMIB_IPADDRTABLE pIpAddrTable,  // 接受获取到的本地计算机网络接口和IP地址的映射表
 *   _inout PULONG pdwSize,				  // 接收收到数据的大小
 *   _in BOOL bOrder					 // 获取到的映射表中是否按IP地址的升序排列
 * );
 *
 * 用于保存IP地址表的PMIB_IPADDRTABLE结构体
 * typedef struct _MIB_IPADDRTABLE{
 *   DWORD      dwNumEntries;					// 表示映射表中记录的数量
 *   MIB_IPADDRROW table[ANY_SIZE];             // MIB_IPADDRROW结构体数组
 * }MIB_IPADDRTABLE, *PMIB_IPADDRTABLE;
 *
 * 用于保存IP地址的结构体
 * typedef struct _MIB_IPADDRROW{
 *   DWORD dwAddr;   // 网络字节序格式的IP地址
 *   DWORD dwIndex;  // 与IP地址相关联的网络编号序号
 *   DWORD dwMask;   // 网络字节序的子网掩码
 *   DWORD dwBCastAddr;  // 网络字节序格式的广播地址
 *   DWORD dwReasmSize;  // 已收到的数据报重装后的最大长度
 *   unsigned short unusedl;  // 预留字段
 *   unsigned short wType;	  // IP地址的类型或状态
 * }MIB_IPADDRROW, *PMIB_IPADDRROW;
 **/

//#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
//#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int GetIpAddrTableFunction()
{
    PMIB_IPADDRTABLE pIPAddrTable;  // 网络接口与IP地址映射表
    DWORD dwSize = 0;   // 获取数据的大小
    DWORD dwRetVal = 0; // 调用GetIPAddrTable()函数的返回值
    IN_ADDR IPAddr;     // 保存IP地址的结构体
    LPVOID lpMsgBuf;    // 用于获取错误信息

    // 分配内存空间
    pIPAddrTable = (MIB_IPADDRTABLE *) MALLOC(sizeof (MIB_IPADDRTABLE));
    // 第1次调用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);
    }

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

	printf("\n");
	system("pause");
	return 0;
}


 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值