VC++实现获取本地主机网卡信息

来源:互联网 发布:数据店长助理 编辑:程序博客网 时间:2024/04/30 01:54

我们在进行网络编程的时候,经常需要获取本地主机,网卡的信息,我们代码实现如下。



#include "../common/initsock.h"#include <windows.h>#include <stdio.h>#include <Iphlpapi.h>#include "protoutils.h"#include "ProtoPacket.h"#pragma comment(lib, "Iphlpapi.lib")DWORD WINAPI SendThread(LPVOID lpParam);BOOL GetGlobalData();/////////////////////////////////////////// 全局数据u_charg_ucLocalMac[6];// 本地MAC地址DWORDg_dwGatewayIP;// 网关IP地址DWORDg_dwLocalIP;// 本地IP地址DWORDg_dwMask;// 子网掩码CInitSock theSock;int main(){// 获取全局数据GetGlobalData();// 启动服务if(!ProtoStartService()){printf(" ProtoStartService() failed %d \n", ::GetLastError());return -1;}// 打开控制设备对象HANDLE hControlDevice = ProtoOpenControlDevice();if(hControlDevice == INVALID_HANDLE_VALUE){printf(" ProtoOpenControlDevice() failed() %d \n", ::GetLastError());ProtoStopService();return -1;}// 枚举绑定的下层适配器CPROTOAdapters adapters;if(!adapters.EnumAdapters(hControlDevice)){printf(" Enume adapter failed \n");ProtoStopService();return -1;}CAdapter adapter;// 默认使用第一个适配器if(!adapter.OpenAdapter(adapters.m_pwszSymbolicLink[0], TRUE)){printf(" OpenAdapter failed \n");ProtoStopService();return -1;}CArpPacket arp(&adapter);////////////////////////////////////////////////////////////////////////// 下面开始进行LAN扫描// 提供当前线程(接收数据的线程)的优先级,避免丢失到来的数据贞::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);// 创建发送线程,开始发送ARP请求::CloseHandle(::CreateThread(NULL, 0, SendThread, &arp, 0, NULL));// 接收ARP应答u_char *p;PARPHeader pArph;printf(" 开始扫描LAN中的计算机... \n");while(TRUE){pArph = arp.WaitReply();if(pArph != NULL){printf(" \n ------------------------------------------- \n");p = pArph->smac;printf("Mac地址:%02X-%02X-%02X-%02X-%02X-%02X \n", p[0], p[1], p[2], p[3], p[4], p[5]);p = (u_char*)&pArph->saddr;printf(" IP地址:%d.%d.%d.%d  \n ", p[0], p[1], p[2], p[3]);//HOSTENT *pHost = ::gethostbyaddr((char*)&pArph->saddr, 4, AF_INET);//if(pHost != NULL)//printf(" 主机名:%s \n", pHost->h_name);}else{break;}}printf("\n\n 扫描完毕 \n");ProtoStopService();getchar();return 0;}DWORD WINAPI SendThread(LPVOID lpParam){CArpPacket *pArp = (CArpPacket *)lpParam;// 取得LAN中IP地址空间的大小DWORD dwMask = ::ntohl(g_dwMask);int nMaxHosts = ~dwMask;// 设置以太头中目标MAC地址。发送ARP请求时,应该将它设为广播地址u_char destmacEther[6];memset(destmacEther, 0xff, 6);// ARP头中的目标MAC地址u_char destmacArp[6] = { 0 }; // 向地址空间中的每个IP地址发送ARP请求DWORD dwTemp = ::ntohl(g_dwGatewayIP & g_dwMask) + 1;for(int i=1; i<nMaxHosts; i++, dwTemp++){DWORD dwIP = ::htonl(dwTemp);if(dwIP != g_dwLocalIP){if(!pArp->SendPacket(destmacEther, g_ucLocalMac, ARPOP_REQUEST, destmacArp, dwIP, g_ucLocalMac, g_dwLocalIP)){printf(" SendPacket() failed \n");break;}}}return 0;}BOOL GetGlobalData(){PIP_ADAPTER_INFO pAdapterInfo = NULL;ULONG ulLen = 0;// 为适配器结构申请内存::GetAdaptersInfo(pAdapterInfo,&ulLen);pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, ulLen);// 取得本地适配器结构信息if(::GetAdaptersInfo(pAdapterInfo,&ulLen) ==  ERROR_SUCCESS){if(pAdapterInfo != NULL){memcpy(g_ucLocalMac, pAdapterInfo->Address, 6);g_dwGatewayIP = ::inet_addr(pAdapterInfo->GatewayList.IpAddress.String);g_dwLocalIP = ::inet_addr(pAdapterInfo->IpAddressList.IpAddress.String);g_dwMask = ::inet_addr(pAdapterInfo->IpAddressList.IpMask.String);}}::GlobalFree(pAdapterInfo);printf(" \n -------------------- 本地主机信息 -----------------------\n\n");in_addr in;in.S_un.S_addr = g_dwLocalIP;printf("      IP Address : %s \n", ::inet_ntoa(in));in.S_un.S_addr = g_dwMask;printf("     Subnet Mask : %s \n", ::inet_ntoa(in));in.S_un.S_addr = g_dwGatewayIP;printf(" Default Gateway : %s \n", ::inet_ntoa(in));u_char *p = g_ucLocalMac;printf("     MAC Address : %02X-%02X-%02X-%02X-%02X-%02X \n", p[0], p[1], p[2], p[3], p[4], p[5]);printf(" \n \n ");return TRUE;}