网络程序设计 实验1 获取主机信息 (MFC 套接字编程)
实验目的:
实现一个获取本地主机信息的可视化软件。能够显示主机名,网卡接口名,网卡的MAC地址,网卡上的IP配置(ip地址,子网掩码)
老实说这一点我没看懂,在这浪费了好多时间
然后我还到处找看看vs有没有socket组件,但是没找到
关于使用MFC的选项要选哪个
找到的资料:
准备打包成exe给老师,那就选静态库吧
(小插曲),
发现我之前一直找不到的‘创建对话框模式的项目时选择”windows”套接字’其实在这里,笑哭
那现在开始吧
首先,建立界面
然后感觉要给编辑框加一下滚动条
所以要把多行设为true(想要返回我也设为true,因为感觉可能需要输入enter)
给输入框绑定一个变量用来显示主机信息(就起名叫hostinfo好了)
双击“这个按钮”,准备编辑按钮按下后运行的代码
ppt上清屏操作的代码,一开始先入为主以为是string,报错了,搜了好久突然发现可能是list
往这个方向找发现实际上是MFC的CListBox类
也就是说,实际上用的控件是list box而不是edit control
代码里虽然有“string”这样的字眼,但是实际和string没有关系。绑定的变量也不是值变量CString,而是控件变量CListBox(ppt里没有写明,这里让我废了挺多脑筋)
添加控件
获取主机名字的代码(大部分都是抄老师ppt的,不过有些没法通过编译,我找些办法改了改)
点击查看代码
int itemcount = m_IPList.GetCount();
for (int i = 0; i < itemcount; i++)
m_IPList.DeleteString(0);//清空输入框
char hostname[256] = "\0";
struct addrinfo* result = NULL;
struct addrinfo* ptr = NULL;
CString s;
if (gethostname(hostname, sizeof(hostname))) {
m_IPList.AddString(L"获取主机名字失败");
}
else {
s += L"主机名字为:";
s += hostname;
m_IPList.AddString(s); //SetWindowText(s);
}
//获取主机名字
如图所示,这就是MAC地址在IP_ADAPTER_ADDRESSES结构体中的类型
参考了其他前辈用sprintf写的读取MAC地址的代码
然后我参考了这篇文章里讲的Format的格式,把MAC地址代码整好了
https://blog.csdn.net/Gordon_Wei/article/details/108115695
点击查看代码
s = L"网卡接口名:";
s += pCurrAddresses->FriendlyName;
m_IPList.AddString(s);
//网卡接口名
s.Format(L"%02X - %02X - %02X - %02X - %02X - %02X",
pCurrAddresses->PhysicalAddress[0], pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2], pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4], pCurrAddresses->PhysicalAddress[5]);
s = L"MAC地址:" + s;
m_IPList.AddString(s);
//MAC地址`
获取IP地址的代码倒是抄PPT抄的很顺利
但是IP地址输出乱码
然后我根据编译器报错找到解决办法了``
https://learn.microsoft.com/en-us/cpp/code-quality/c6302?view=msvc-170
全套消息处理代码
点击查看代码
void Clab1Dlg::OnBnClickedSocket(){
int itemcount = m_IPList.GetCount();
for (int i = 0; i < itemcount; i++)
m_IPList.DeleteString(0);//清空输入框
char hostname[256] = "\0";
struct addrinfo* result = NULL;
struct addrinfo* ptr = NULL;
CString s;
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
ULONG outBufLen = 0;
DWORD dwRetVal = 0;
ULONG Iterations = 0;
unsigned int i = 0;
char strIP[16];
if (gethostname(hostname, sizeof(hostname))) {
m_IPList.AddString(L"获取主机名字失败");
}
else {
s = L"主机名字为:";
s += hostname;
m_IPList.AddString(s); //SetWindowText(s);
}
//获取主机名字
do {
pAddresses = (IP_ADAPTER_ADDRESSES*)HeapAlloc(GetProcessHeap(), 0, outBufLen);
if (pAddresses == NULL) {
s = L"Memory allocation failed for IP_ADAPTER_ADDRESSES struct";
m_IPList.AddString(s);
exit(1);
}
dwRetVal = GetAdaptersAddresses(AF_INET, 0, NULL, pAddresses, &outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
HeapFree(GetProcessHeap(), 0, pAddresses);
pAddresses = NULL;
}
else {
break;
}
Iterations++;
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < 3));
//PPT上MAX_TRIES在宏定义里设置为3,我这里图省事直接写了个3
if (dwRetVal == NO_ERROR) {
pCurrAddresses = pAddresses;
while (pCurrAddresses) {
s = L"网卡接口名:";
s += pCurrAddresses->FriendlyName;
m_IPList.AddString(s);
//网卡接口名
s.Format(L"%02X - %02X - %02X - %02X - %02X - %02X",
pCurrAddresses->PhysicalAddress[0], pCurrAddresses->PhysicalAddress[1],
pCurrAddresses->PhysicalAddress[2], pCurrAddresses->PhysicalAddress[3],
pCurrAddresses->PhysicalAddress[4], pCurrAddresses->PhysicalAddress[5]);
s = L"MAC地址:" + s;
m_IPList.AddString(s);
//MAC地址
pUnicast = pCurrAddresses->FirstUnicastAddress;
if (pUnicast != NULL) {
for (i = 0; pUnicast != NULL; i++) {
sockaddr_in sa = *(sockaddr_in*)(pUnicast->Address.lpSockaddr);
inet_ntop(AF_INET, &sa.sin_addr, strIP,16);
s.Format(L"%hs", strIP);
s = L"IP地址:" + s;
m_IPList.AddString(s);
//IP地址
s.Format(L"%d", pUnicast->OnLinkPrefixLength);
s = L"掩码长度为:" + s;
m_IPList.AddString(s);
//掩码长度
pUnicast = pUnicast->Next;
}
}
//网卡IP
pCurrAddresses = pCurrAddresses->Next;
}
}