[Win32]本地计算机网络信息的获取
2014-07-29 00:05
429 查看
// getNativeComputerNetInformation.cpp /* 在网络编程中,服务器端需要知道本机的IP;唯一标识一台机器的MAC地址; 功能的实现都非常简单,有五种函数可以直接调用: 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 ); */ #include <stdio.h> #include <WinSock2.h> #include <iphlpapi.h> #pragma comment(lib, "IPHLPAPI.lib") #pragma comment(lib, "ws2_32.lib") void 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); } /** * 用于获取本地网络适配器信息的函数: * DWORD GetAdaptersInfo( * _in PIP_ADAPTER_INFO pAdapterInfo; // 结构体保存获取到的网络适配器的信息 * _out PULONG pOutBufLen // 保存pAdapterInfo缓冲区的大小 * ); * * 网络适配器的信息的结构体:网卡信息有:网卡名,网卡描述,MAC地址,网卡IP,网卡默认网关等 * 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; typedef struct _IP_ADDR_STRING { //存储一个IP地址和其相应的子网掩码,同时作为点分十进制的字符串 struct _IP_ADDR_STRING* Next; //由于一个网卡可能有多个IP,故为链表结构 IP_ADDRESS_STRING IpAddress; IP_MASK_STRING IpMask; DWORD Context; } IP_ADDR_STRING, *PIP_ADDR_STRING; typedef struct { //存储一个IP地址,同时作为点分十进制的字符串 char String[4 * 4]; } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING; **/ //一台机器上可能不止有一个网卡,但每一个网卡只有一个MAC地址,而每一个网卡可能配置多个IP地址;如平常的笔记本电脑中,就会有无线网卡和有线网卡两种;因此,如果要获得本机所有网卡的IP和MAC地址信息,则必须顺序获得每个网卡,再依次获取其信息; int GetAdaptersInfoFunction() // 获取本地网络适配器信息的函数 { // 变量声明 IP_ADAPTER_INFO *pAdapterInfo; // 指定获取到的网络信息结构体链表的指针 ULONG ulOutBufLen; // 获取到网络信息结构体链表的长度 DWORD dwRetVal; // 返回调用编码 // 获取本地网络适配器的信息 // 为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获取并显示本地网络信息 PIP_ADAPTER_INFO pAdapter; 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]);//x十六进制(x:会是a,b,c,d,e;X:会是A,B,C,D,E) } } 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 // 接到数据的大小 * ); * typedef struct _IP_INTERFACE_INFO { LONG NumAdapters; IP_ADAPTER_INDEX_MAP Adapter[1]; } IP_INTERFACE_INFO,*PIP_INTERFACE_INFO; * 用于保存计算机网络接口信息的结构体 * 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; }
结果:
相关文章推荐
- [Win32]本地计算机网络信息的获取
- [Win32]本地计算机网络信息的获取
- 本地计算机网络信息的获取
- 本地计算机网络信息的获取
- 计算机网络课程设计二——获取本地适配器的主要信息
- 本地计算机网络信息的获取
- 获取本地网络中可用的SQL Server实例信息
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第十八节 在本地电脑的地址解析协议(ARP )表中创建和删除一个ARP
- 获取本地计算机网络参数
- C#小技巧系列之四:获取本地网络信息
- Qt4获取本地网络信息
- 获取本地网络信息(Csharp2005)
- C#小技巧系列之四:获取本地网络信息
- C#小技巧系列之四:获取本地网络信息
- 获取计算机网络信息,包含IP,MAC
- Android 获取本地外网IP、内网IP、计算机名等信息
- 获取本地网络信息
- Windows获取本地机器的全部网络配置信息
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第十八节 在本地电脑的地址解析协议(ARP )表中创建和删除一个ARP