姓名
学号
班级
年级
指导教师
西安财经学院信息学院 《网络程序设计》 实验报告
实验名称 获取主机网卡信息和子网掩码 实验室 实验楼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,则其网络ID为202.119.115,主机ID为83。因为这两台主机的网络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:网关地址链表。 DhcpServer:DHCP服务器地址,只有在“DhcpEnable==TRUE”时才有效。 清明三年级作文300字 HaveWins:是否启用了WINS。 PrimaryWinsServer:主WINS地址。 SecondaryWinsServer:辅WINS地址。 LeaseObtained:当前DHCP租借获取的时间。 LeaseExpires:当前DHCP租借失效的时间。 LeaseObtained和情侣网名 情侣专用WRTYUILeaseExpires这两个数据结构只有在启动了DHCP时才有效。 该结构成员变量PrimaryWinsServer和SecondaryWinsServer的类型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.h、IpExport.h、IpTypes.h、Iprtrmib.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小时内删除。
发表评论