zoukankan      html  css  js  c++  java
  • VC++实现获取本地主机网卡信息

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



    #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_char	g_ucLocalMac[6];	// 本地MAC地址
    DWORD	g_dwGatewayIP;		// 网关IP地址
    DWORD	g_dwLocalIP;		// 本地IP地址
    DWORD	g_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;
    }
    


  • 相关阅读:
    win shift s截图不能用(已解决)
    阿里云ssl证书过期怎么解决 (免费SSL证书) 三步解决
    图解 Java 数据结构
    微信小程序简介
    序列化类外键字段的覆盖,十大接口序列化总结,视图家族
    response二次封装,夺标关系优化,多表序列化,十大接口
    内部类,drf响应类,序列化与反序列化
    drf以及django应用
    DRF框架知识总览
    实例成员:计算属性 监听属性以及vue的项目开发
  • 原文地址:https://www.cnblogs.com/new0801/p/6177710.html
Copyright © 2011-2022 走看看