计算机网络作业
平台: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;