计算机网络课程设计,使用MFC实现界面化创建ARP发送与接受程序(五)
ARP接收相关函数实现及API调用
关于界面初始化相关代码参考上一篇
主体接收函数
while (true)
{
//使用pcap_next_ex捕获数据报
pcap_next_ex(currentOpenDev, &hdr, &pkt_data);
unsigned char* data = NULL; //定义获取的数据包
data = (unsigned char*)pkt_data; //将捕获的数据包赋值
unsigned char GetFrame[60]; //用于转换格式
for (int i=0; i < 60; i++) //将data转换为char[60] 方便获取数据
{
GetFrame[i] = *data;
*data = *data + 1;
}
//限定格式,使捕获的数据包为指定的数据包
if (data[12] == 0x08 && data[13] == 0x06 && data[20] == 0x00 && data[21] == 0x02)
{
//将发送IP写入字符串中
str.Format("%d.%d.%d.%d", data[28], data[29], data[30], data[31]);
in_addr ipAddress;
//将点分十进制的IP转换成一个长整数型数存入定义的ipAddress中
ipAddress.S_un.S_addr = inet_addr(str);
//定义主机信息结构体
hostent* pht = NULL;
//通过ip地址获取设备信息
pht = gethostbyaddr((char*)&ipAddress, sizeof(ipAddress), AF_INET);
//当主机信息不空时,输出主机名
if (pht != NULL)
{
str.Format("发送ip:%d.%d.%d.%d 发送mac:%02X-%02X-%02X-%02X-%02X-%02X 发送主机名:%15s",
data[28], data[29], data[30], data[31],
data[6], data[7], data[8], data[9], data[10], data[11]
, pht->h_name
);
}
//无法获取主机信息则输出未知主机名
else
{
str.Format("发送ip:%d.%d.%d.%d 发送mac:%02X-%02X-%02X-%02X-%02X-%02X 发送主机名:%15s",
data[28], data[29], data[30], data[31],
data[6], data[7], data[8], data[9], data[10], data[11]
, "未知主机名"
);
}
//通过AddString方法直接向主线程界面更新数据
crlg->INF.AddString(str);
//crlg->m_ComboxResults.Invalidate(); //这句是刷新界面,True刷新,False则不刷新
}
}
注意,相比较ARP发送程序,ARP接收程序必须使用多线程来实现,因为我们要一边接收发来的数据包信息,一边向主界面添加相关信息,若使用单线程,则程序无法满足需求,相关多线程代码如下:
//开始按钮的设计
void CRECARPMFCDlg::OnBnClickedStartBut()
{
//将所有设备信息赋值
SelectedAdapter = pAdapter;
CString selectedItem;
//获取当前ComboBox所选数据
DEC_COM.GetLBText(DEC_COM.GetCurSel(), selectedItem);
//循环将选择设备赋值
while (SelectedAdapter->Description != selectedItem)
{
SelectedAdapter = SelectedAdapter->Next;
}
// TODO: 在此添加控件通知处理程序代码
if (SelectedAdapter == 0)
{
MessageBox("请先于左侧框内选择设备!");
}
else
{
//将停止按钮恢复,将开始按钮设为FALSE
END.EnableWindow(TRUE);
START.EnableWindow(FALSE);
//若线程为空,则开始线程工作
if (m_Thread == NULL)
{
m_Thread = CreateThread(NULL, 0, RecInf, this, 0, NULL);
}
else
{
ResumeThread(m_Thread);
}
}
}
//暂停按钮的设计
void CRECARPMFCDlg::OnBnClickedEndBut()
{
//将停止按钮设为FALSE,启动按钮恢复工作
END.EnableWindow(FALSE);
START.EnableWindow(TRUE);
//暂停线程的工作
SuspendThread(m_Thread);
}
DWORD WINAPI RecInf(LPVOID lpParameter)
{
CRECARPMFCDlg* crlg = (CRECARPMFCDlg*)lpParameter;
......
}
有关IP Helper和WINPCAP相关调用参考上一节内容,代码一致,这里不再搬运。
相对于ARP发送,接收比较简单,相关参考文章如下:
MFC界面编程: 为 Arp协议获得本地局域网内在线主机MAC地址的程序 编写 界面