Windows使用C++获取网卡信息

17 篇文章 3 订阅

使用 Windows sdk 提供的 API 函数 GetAdaptersInfo() 可以获得本机所有网卡的网卡名 , 网卡描述 , 网卡 MAC 地址 , 网卡IP , 网卡类型等信息 , 并用 IP_ADAPTER_INFO 结构体存储 ; 使用 GetIfEntry() 可以获取网卡的状态 , 可有效判断出网卡通讯是否正常 , 是否插入网线等状态 ; 代码如下 :

#include "stdafx.h"
#include <WinSock2.h>
#include <Iphlpapi.h>
#include <iostream>
using namespace std;
#pragma comment(lib,"Iphlpapi.lib")

// 声明获取网卡状态信息函数
bool GetAdapterState(DWORD index);

int main()
{
    _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
    // PIP_ADAPTER_INFO 结构体指针存储本机网卡信息
    PIP_ADAPTER_INFO pIPAdapterInfo = new IP_ADAPTER_INFO();
    PIP_ADAPTER_INFO pAdapter = NULL;
    // 得到结构体大小 , 用于 GetAdaptersInfo 参数
    unsigned long ulSize = sizeof(IP_ADAPTER_INFO);
    // 调用 GetAdaptersInfo 函数 , 填充 pIpAdapterInfo 指针变量 , 其中 ulSize 参数既是一个输入量也是一个输出量
    int nRstCode = GetAdaptersInfo(pIPAdapterInfo, &ulSize);
    // 记录网卡数量
    int nNetCardNum = 0;
    // 记录每张网卡上的 IP 地址数量
    int nIPNumPerNetCard = 0;
    if (ERROR_BUFFER_OVERFLOW == nRstCode)
    {
        // 如果函数返回的是 ERROR_BUFFER_OVERFLOW
        // 则说明 GetAdaptersInfo 参数传递的内存空间不够 , 同时其传出 ulSize , 表示需要的空间大小
        // 这也是说明为什么 ulSize 既是一个输入量也是一个输出量
        // 释放原来的内存空间
        delete pIPAdapterInfo;
        // 重新申请内存空间用来存储所有网卡信息
        pIPAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[ulSize];
        // 再次调用 GetAdaptersInfo 函数 , 填充 pIpAdapterInfo 指针变量
        nRstCode = GetAdaptersInfo(pIPAdapterInfo, &ulSize);    
    }
    if (ERROR_SUCCESS == nRstCode)
    {
        // 输出网卡信息 , 可能有多网卡 , 因此通过循环去判断
        pAdapter = pIPAdapterInfo;
        while (pAdapter)
        {
            cout<<"网卡数量 : "<<++nNetCardNum<<endl;
            cout<<"网卡名称 : "<<pAdapter->AdapterName<<endl;
            cout<<"网卡描述 : "<<pAdapter->Description<<endl;
            switch(pAdapter->Type)
            {
            case MIB_IF_TYPE_OTHER:
                cout<<"网卡类型 : "<<"OTHER"<<endl;
                break;
            case MIB_IF_TYPE_ETHERNET:
                cout<<"网卡类型 : "<<"ETHERNET"<<endl;
                break;
            case MIB_IF_TYPE_TOKENRING:
                cout<<"网卡类型 : "<<"TOKENRING"<<endl;
                break;
            case MIB_IF_TYPE_FDDI:
                cout<<"网卡类型 : "<<"FDDI"<<endl;
                break;
            case MIB_IF_TYPE_PPP:
                cout<<"网卡类型 : "<<"PPP"<<endl;
                break;
            case MIB_IF_TYPE_LOOPBACK:
                cout<<"网卡类型 : "<<"LOOPBACK"<<endl;
                break;
            case MIB_IF_TYPE_SLIP:
                cout<<"网卡类型 : "<<"SLIP"<<endl;
                break;
            default:
                break;
            }
            cout<<"网卡MAC地址 : ";
            for (DWORD i=0; i<pAdapter->AddressLength; i++)
            {
                if (i < pAdapter->AddressLength-1)
                {
                    printf("%02X-", pAdapter->Address[i]);
                }
                else
                {
                    printf("%02X\n", pAdapter->Address[i]);
                }
            }
            cout<<"网卡IP地址如下 : "<<endl;
            // 可能网卡有多 IP , 因此通过循环去判断
            IP_ADDR_STRING *pIPAddrString =&(pAdapter->IpAddressList);
            nIPNumPerNetCard = 0;
            while (pIPAddrString)
            {
                cout<<"该网卡上的IP数量 : "<<++nIPNumPerNetCard<<endl;
                cout<<"IP 地址 : "<<pIPAddrString->IpAddress.String<<endl;
                cout<<"子网地址 : "<<pIPAddrString->IpMask.String<<endl;
                cout<<"网关地址 : "<<pAdapter->GatewayList.IpAddress.String<<endl;
                pIPAddrString=pIPAddrString->Next;
            }
            if (GetAdapterState(pAdapter->Index))
            {
                cout<<"网卡工作正常"<<endl;
            }
            else
            {
                cout<<"网卡工作异常"<<endl;
            }
            pAdapter = pAdapter->Next;
            cout<<"--------------------------------------------------------------------"<<endl;
        }
    }
    // 释放内存空间
    if (pIPAdapterInfo != NULL)
    {
        delete[] pIPAdapterInfo;
        pIPAdapterInfo = NULL;
    }
    getchar();
    return 0;
}

bool GetAdapterState(DWORD nIndex)
{
    MIB_IFROW miInfo;   // 存放获取到的 Adapter 参数
    memset(&miInfo, 0, sizeof(MIB_IFROW)) ; 
    miInfo.dwIndex = nIndex;   // dwIndex 是需要获取的 Adapter 的索引
    if(GetIfEntry(&miInfo) != NOERROR)
    {
        printf("ErrorCode = %d\n" ,GetLastError());
        return false;
    }
    if(miInfo.dwOperStatus==IF_OPER_STATUS_NON_OPERATIONAL || miInfo.dwOperStatus==IF_OPER_STATUS_UNREACHABLE
        || miInfo.dwOperStatus==IF_OPER_STATUS_DISCONNECTED || miInfo.dwOperStatus==IF_OPER_STATUS_CONNECTING)
    {
        return false;
    }
    else if(miInfo.dwOperStatus==IF_OPER_STATUS_OPERATIONAL || miInfo.dwOperStatus == IF_OPER_STATUS_CONNECTED)
    {
        return true;
    }
    else
    {
        return false;
    }
}

原文点击 : http://blog.csdn.net/lusirking/article/details/51780848

个人网站: Github , 欢迎点击给星

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值