获取主机网卡信息——实验报告
姓名               
学号               
班级               
年级             
指导教师           
西安财经学院信息学院
  《网络程序设计》    实验报告
实验名称 获取主机网卡信息和子网掩码 实验室 实验楼402 实验日期             
喀什旅游
一、实验目的
  了解如何编写程序实现获取本地主机的网卡信息和子网掩码。
2、实验要求
  获得本地计算机的网络信息,从而获得计算机的网卡名、网卡驱动程序、IP地址、子网掩码、物理地址、是否启用了DHCP、是否启用了WINS等网络信息。
3、实验内容
  利用GetAdaptersInfo函数获取计算机的网络信息。
4、实验原理
TCP/IP协议中,子网掩码是用来区分网络上的主机是否在同一网络段内的。假如某主机的IP地址为202.119.115.78,它的子网掩码为255.255.255.0,将这两个数据做AND运算,则所得的值中非零的部分即为网络ID。运算步骤如下:
  (1)IP地址202.119.115.78的二进制值为11001010.01110111.01110011.01001110
  (2) 子网掩码255.255.255.0的二进制值为11111111.11111111.11111111.00000000
    (3) 将两者做AND计算,其结果为11001010.01110111.01110011.00000000
(4) 将结果转换成十进制后为202.119.115.0,其非零部分202.119.115就是网络ID,在IP地址中剩下的为主机ID,本例中为78。这样如果另一台主机的IP地址为202.119.115.83,其子网掩码为255.255.255.0,则其网络ID202.119.115,主机ID83。因为这两台主机的网络ID均为202.119.115,因此这两台主机在同一网段内。
函数GetAdaptersInfo可以获得本地计算机的网络信息,从而获得该计算机的网卡名、网卡驱动程序、IP地址、子网掩码、物理地址、是否启用了DHCP、是否启用了WINS等网络信息。注意该函数在头文件IpHlpApi.h中声明,库文件为IpHlpApi.lib。函数原型为:
  DWORD GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
其中:
  参数pAdapterInfo指向IP_ADAPTER_INFO结构链表缓冲区的指针;
  参数pOutBufLen指向一个ULONG变量的指针,该ULONG变量表示指向pAdapterInfo结构的大小。 无法获取ip地址
  参数中的IP_ADAPTER_INFO结构包含了本地计算机上一个特定网络适配卡的信息,该结构格式如下:
typedef struct _IP_ADAPTER_INFO
{
struct _IP_ADAPTER_INFO* Next;//指向链表中下一个适配器信息的指针
DWORD  ComboIndex;//预留值
选车牌号char    AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//使用ANSI字符串表示的适配器名称
char    Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//使用ANSI字符串表示的适配器描述
UINT    AddressLength;//适配器硬件地址以字节计算的长度
BYTE    Address[MAX_ADAPTER_ADDRESS_LENGTH];//硬件地址以BYTE数组所表示
DWORD  Index;//适配器索引
UINT    Type;//适配器类型
UINT    DhcpEnabled;//指定这个适配器是否开启DHCP
PIP_ADDR_STRING    CurrentIpAddress;//预留值
IP_ADDR_STRING      IpAddressList;//该适配器的IPv4地址链表
IP_ADDR_STRING      GatewayList;//该适配器的网关IPv4地址链表
IP_ADDR_STRING      DhcpServer;//该适配器的DHCP服务器的IPv4 地址链表
BOOL                HaveWins;
IP_ADDR_STRING      PrimaryWinsServer;
IP_ADDR_STRING      SecondaryWinsServer;
time_t        LeaseObtained;
time_t        LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
其中成员变量的具体含义如下:
  Next:链表指针域,通过这个变量来遍历静态链表。
  ComboIndex:保留未用。
  AdapterName[MAX_ADAPTER_NAME_LENGTH+4]:网卡名。
  Description[MAX_ADAPTER_DESCRIPTION_LENGTH+4]:对网卡的描述,实际上是驱动程序的名字。
  AddressLength:物理地址的长度,通过该变量才能正确地显示下面数组中的物理地址。
  Address[MAX_ADAPTER_ADDRESS_LENGTH]:物理地址,每个字节存放一个十六进制的数值。
  Index:网卡索引号。
    Type:网卡类型。
  元旦朋友圈文案DhcpEnable是否启用了DHCP动态IP分配。
  CurrentIpAddress:当前使用的IP地址。
  IpAddressList:绑定到此网卡的IP地址链表。
  GetwayList:网关地址链表。
  DhcpServerDHCP服务器地址,只有在“DhcpEnable==TRUE”时才有效。
清明三年级作文300字
  HaveWins:是否启用了WINS
  PrimaryWinsServer:主WINS地址。
  SecondaryWinsServer:辅WINS地址。
    LeaseObtained:当前DHCP租借获取的时间。
  LeaseExpires:当前DHCP租借失效的时间。 
   LeaseObtained情侣网名 情侣专用WRTYUILeaseExpires这两个数据结构只有在启动了DHCP时才有效。
该结构成员变量PrimaryWinsServerSecondaryWinsServer的类型IP_ADDR_STRING结构代表IP地址链表的一个节点,其定义如下:
该结构表示IP地址链表,即一组IP地址。
typedef struct _IP_ADDR_STRING{
struct _IP_ADDR_STRING*    Next;
IP_ADDRESS_STRING          IpAddress;
IP_MASK_STRING            IpMask;
DWORD                      Context;
}IP_ADDR_STRING;
字段说明:
Next: 指向表中的下一个IP_ADDR_STRING结构
IpAddress 一个字符串,它描述了点分十进制IP地址
IpMask 与上面的IpAddress关联的IP地址掩码
Context 网络表入口。
5、实验步骤
利用Visual C++创建工程时,选择Win32 Console Application,程序运行之后是个DOS模式界面。为了利用GetAdaptersInfo函数获取计算机的网络信息,必须在创建的工程中添加入头文件IpHlpApi.hIpExport.hIpTypes.hIprtrmib.h和库文件IpHlpApi.lib。具体的实现代码如下:
#include<winsock2.h>
#include"Iphlpapi.h"
#include<stdio.h>
#pragma comment(lib,"Iphlpapi.lib")
int main()
{
    PIP_ADAPTER_INFO pAdapterInfo;  //pAdapterInfo指向结构体_IP_ADAPTER_INFO的指针
    PIP_ADAPTER_INFO pAdapter = NULL;  //pAdapter指向结构体_IP_ADAPTER_INFO的指针为空
    DWORD dwRetVal = 0;
    ULONG ulOutBufLen;
    pAdapterInfo=(PIP_ADAPTER_INFO)malloc(sizeof(IP_ADAPTER_INFO));//pAdapterInfo指向IP_ADAPTER_INFO结构链表缓冲区的指针;Malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针
    ulOutBufLen = sizeof(IP_ADAPTER_INFO);//结构体大小
    // 第一次调用GetAdapterInfo获取ulOutBufLen大小
    if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)//There is not enough space on the disk.
    {
        free(pAdapterInfo);//释放内存空间
        pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); //pAdapterInfo指向IP_ADAPTER_INFO结构链表缓冲区的指针;
    }
   
    if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
    {
        pAdapter = pAdapterInfo;
        HKEY hKEY;//要 查询的键的 句柄
        while (pAdapter)
        {
            printf("Adapter Name: \t%s\n", pAdapter->AdapterName);
            //////////////////////////////////////////////////////////////////////////////////////
            char path[MAX_PATH]="\0";
            sprintf(path,"SYSTEM\\ControlSet001\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",pAdapter->AdapterName);
            //打开一个指定的注册表键
            long ret=::RegOpenKeyEx(HKEY_LOCAL_MACHINE,path, 0, KEY_READ,&hKEY); //指向一个被打开键返回的句柄的指针
            if(ret!=ERROR_SUCCESS) //如果无法打开hKEY,则终止程序的执行
            {
                printf("Error !\n");
                return 0;
            }
            //回所打开注册表键所关联的一个给定值的类型和数据。
            unsigned char tmp[256]="\0";
            DWORD type=REG_SZ;
            DWORD size=80;
            ret=::RegQueryValueEx(hKEY,"Name", NULL,&type,tmp,&size);
            if(ret!=ERROR_SUCCESS)
            {
                printf("Error !\n");
                return 0;
            }
            ::RegCloseKey(hKEY);//释放指定注册键的句柄函数
            printf("Adapter Chinese Name:\t%s\n",tmp);
            //////////////////////////////////////////////////////////////////////////////////////
            printf("Adapter Desc: \t%s\n", pAdapter->Description);
            printf("MAC Addr: \t%02x-%02x-%02x-%02x-%02x-%02x\n", //%02x,不足两位前面补零
                pAdapter->Address,pAdapter->Address,pAdapter->Address,
                pAdapter->Address,pAdapter->Address,pAdapter->Address
                );
            printf("IP Address: \t%s\n", pAdapter->IpAddressList.IpAddress.String);
            printf("IP Mask: \t%s\n", pAdapter->IpAddressList.IpMask.String);
            printf("Gateway: \t%s\n", pAdapter->GatewayList.IpAddress.String);
            pAdapter = pAdapter->Next;
        }
    }
    else
    {
        printf("Call to GetAdaptersInfo failed.\n");
    }
    system("pause");
    return 0;
}
  运行结果:
       
6、实验总结

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。