文章标题

计算机网络作业


平台:Windows 7
软件:Visual Studio 2015
题目:做一个具有界面的软件,功能为显示本机网卡信息


设计过程

使用VS2015创建一个MFC项目,类型为基于对话框
这里写图片描述

在界面设计拖入combo部件,button部件,edit部件等,修改部件的属性,最终效果如下图
软件的界面

界面右键,类向导,为combo部件和edit部件添加变量
这里写图片描述

主要代码

头文件和变量设置
temp_Description[5] ——网卡描述;
temp_AdapterName[5]——网卡名称;
temp_Address[5]——IP地址;
IpAddress[5]——MAC地址;
IpMask[5]——子网掩码;
GatewayList[5]——网关;

#include "stdafx.h"
#include "MFCApplication2.h"
#include "MFCApplication2Dlg.h"
#include "afxdialogex.h"
#include <WinSock2.h>  
#include <iphlpapi.h>  

#pragma comment(lib, "IPHLPAPI.lib")  
#pragma comment(lib, "ws2_32.lib")  

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CString temp_Description[5], temp_AdapterName[5], temp_Address[5], IpAddress[5], IpMask[5], GatewayList[5];
int temp_i = 0;

fun函数(根据getadaotersInfo函数写)

//fun函数用于获取网卡的基本信息
void fun() {
    //PIP_ADAPTER_INFO结构体指针存储本机网卡信息
    PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
    //得到结构体大小,用于GetAdaptersInfo参数
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);
    //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量
    int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    //记录网卡数量
    int netCardNum = 0;
    //记录每张网卡上的IP地址数量
    int IPnumPerNetCard = 0;
    if (ERROR_BUFFER_OVERFLOW == nRel)
    {
        //如果函数返回的是ERROR_BUFFER_OVERFLOW
        //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小
        //这也是说明为什么stSize既是一个输入量也是一个输出量
        //释放原来的内存空间
        delete pIpAdapterInfo;
        //重新申请内存空间用来存储所有网卡信息
        pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
        //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量
        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    }
    if (ERROR_SUCCESS == nRel)
    {
        //输出网卡信息
        //可能有多网卡,因此通过循环去判断
        while (pIpAdapterInfo)
        {
            temp_Description[temp_i] = pIpAdapterInfo->Description;//获取网络适配器描述
            temp_AdapterName[temp_i] = pIpAdapterInfo->AdapterName;//获取网络适配器名称
            IpAddress[temp_i] = pIpAdapterInfo->IpAddressList.IpAddress.String;//获取对应IP地址
            IpMask[temp_i] = pIpAdapterInfo->IpAddressList.IpMask.String;//获取对应子网掩码
            GatewayList[temp_i] = pIpAdapterInfo->GatewayList.IpAddress.String;//获取对应网关

            //获取网卡mac地址
            for (unsigned int i = 0; i < pIpAdapterInfo->AddressLength; i++)
                if (i == (pIpAdapterInfo->AddressLength - 1))
                {
                    temp_Address[temp_i] += pIpAdapterInfo->Address[i];

                }
                else
                {
                    temp_Address[temp_i] += pIpAdapterInfo->Address[i];
                    temp_Address[temp_i] += "-";
                }

            temp_i++;
            pIpAdapterInfo = pIpAdapterInfo->Next;//下一个网络适配器
        }

    }
    if (pIpAdapterInfo)//结束释放空间
    {
        delete pIpAdapterInfo;
    }
}

在BOOL CMFCApplication2Dlg::OnInitDialog()函数中进行软件的初始化:
1.运行fun函数;
2.获取得到的所有网络适配器的描述传递个combo部件的变量。

fun();
for (int a= temp_i -1; a >= 0; a--)
    m_combo_name.AddString(temp_Description[a]);

双击button部件输入对应的按键代码

void CMFCApplication2Dlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
    UpdateData(true);
    CString prt, Description;
    m_combo_name.GetWindowTextW(Description);//获取 combo部件当前被选中的网卡名称
    for(int b=0;b<5;b++)//搜索选中的网卡
        if (Description == temp_Description[b])
        {
        //在edit部件中输出网卡信息
            prt += "网络适配器名:";
            prt += temp_AdapterName[b]; prt += "\r\n";
            prt += "网络适配器描述:";
            prt += Description; prt += "\r\n";
            prt += "MAC地址:";
            prt += temp_Address[b]; prt += "\r\n";
            prt += "IP地址:";
            prt += IpAddress[b]; prt += "\r\n";
            prt += "子网掩码:";
            prt += IpMask[b]; prt += "\r\n";
            prt += "网关:";
            prt += GatewayList[b]; prt += "\r\n";
        }
    m_edit.SetWindowTextW(prt);//在edit部件中显示prt中的信息
    UpdateData(false);
}

测试

这里写图片描述
这里写图片描述


bug

GetAdaptersInfo函数返回的MAC地址为(byte)型,而temp_address为CString型,所有最后输出的时候会出现乱码。
解决方法:进行格式转换

http://blog.csdn.net/wangandy7811/article/details/4619930


GetAdaptersInfo函数

/**
 * 用于获取本地网络适配器信息的函数:
 * DWORD GetAdaptersInfo(
 *   _in PIP_ADAPTER_INFO pAdapterInfo;    // 结构体保存获取到的网络适配器的信息
 *   _out PULONG pOutBufLen                // 保存pAdapterInfo缓冲区的大小
 * );
 *
 * 网络适配器的信息的结构体:网卡信息有:网卡名,网卡描述,MAC地址,网卡IP,网卡默认网关等
 * typedef struct _IP_ADAPTER_INFO {
 *   struct _IP_ADAPTER_INFO* Next;                 // 指定网络适配器链表中的下一个网络适配器;由于一台电脑可能有多个网卡,所以是链表结构
 *   DWORD ComboIndex;                              // 预留变量
 *   char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; // 网络适配器的名称
 *   char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];  // 网络适配器的描述信息
 *   UINT AddressLength;                            // 网络适配器MAC的长度
 *   BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];      // 网络适配器的MAC地址
 *   DWORD Index;                                   // 网络适配器索引(重启计算机会改变的值)
 *   UINT Type;                                     // 网络适配器的类型
 *   UINT DhcpEnabled;                              // 指定该网络适配器上是否启用了DHCP
 *   PIP_ADDR_STRING CurrentIpAddress;              // 预留变量
 *   IP_ADDR_STRING IpAddressList;                  // 与此网络适配器上相关联的IP地址列表
 *   IP_ADDR_STRING GatewayList;                    // 该网络适配器上定义的IP地址的默认网关
 *   IP_ADDR_STRING DhcpServer;                     // 该网络适配器上定义的DHCP服务器的IP地址
 *   BOOL HaveWins;                                 // 标明该网络适配器是否启用了WINS
 *   IP_ADDR_STRING PrimaryWinsServer;              // 主WIN服务器的IP地址
 *   IP_ADDR_STRING SecondaryWinsServer;            // 从WINS服务器的IP地址
 *   time_t LeaseObtained;                          // 当前的DHCP租借获取的时间,只有在启用DHCP时生效
 *   time_t LeaseExpires;                           // 当前的DHCP租借失败的时间,只有在启用DHCP时生效
 * } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;


 typedef struct _IP_ADDR_STRING {   //存储一个IP地址和其相应的子网掩码,同时作为点分十进制的字符串
 struct _IP_ADDR_STRING* Next; //由于一个网卡可能有多个IP,故为链表结构
 IP_ADDRESS_STRING IpAddress;
 IP_MASK_STRING IpMask;
 DWORD Context;
 } IP_ADDR_STRING, *PIP_ADDR_STRING;

 typedef struct {            //存储一个IP地址,同时作为点分十进制的字符串
 char String[4 * 4];
 } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值