MFC界面编程: 为 Arp协议获得本地局域网内在线主机MAC地址的程序 编写 界面

本文档详细介绍了如何使用MFC框架开发一个基于对话框的程序,用于通过Arp协议获取本地局域网内在线主机的MAC地址。在MFC中创建界面并实现多线程,主线程负责界面,工作线程负责数据获取。文中还讨论了如何将新代码与原有代码融合,以及在处理线程与界面交互时的注意事项。
摘要由CSDN通过智能技术生成

Section I Problem Specification

本次实验是用C/C++是在上一次实验:使用Arp协议获得本地局域网内在线主机MAC地址的基础上,进行一次的扩展。主要是做一个界面,并且因为要做界面多出了一个多线程的问题。出现多线程的原因是:必须有一个线程用于处理界面的事件。如此一说,反而像是我们在原来的基础上多做了一个线程,然后让这个线程去处理界面的事件,但实际情况不是这样。这是因为我在制作这种基于windows窗体程序的时候,基于了一个框架——MFC。这个框架可以理解为:微软专门为方便开发windows窗体程序的而设计的程序。在我以往的经验中,遇见了google专门为方便开发android应用而设计的程序,那时我管它叫sdk:Software Development Kit, 即软件开发工具包。

在这个框架下开发windows应用,无疑是非常方便的,但是我们也必须遵循这个框架已有的规矩:主线程就是控制界面的线程,这一点与我前面所说的多一个线程来控制界面相反。是在本来就有的界面线程的基础上,我创建了一个新的线程:来发包和收报在这次编写windows的程序过,我遇见了很多与开发android应用一样的准则。比如说:只要主线程才能更新界面,所以,当工作线程想要更新界面,也只有委托主线程。又比如:可以采用拖拉的方式来对界面进行布局,直观而又快速。

固,此次实验的重点是

1.制作界面。

2.多线程的应用。

3.与已有代码的融合。

 

Section II Solution Method and Design

对于界面的制作:

先利用MFC建立一个基于对话框的程序。当如此选择确定之后,MFC已经为我们生成了许多的内容。主要是对话框这个类以及初始化对话框的一些代码。此时,我们可以直接编译,会运行出现一个对话框。我们可以在资源视图内选择该对话框,再在工具箱内找到许多控件,这些控件包括:按钮,checkbox,listbox等等。我们可以直接拖动将其放置在对话框内。此时有4个要点:

1.       双击控件,可以直接调转到该控件的监听事件,比如:双击按钮控件就跳转到一个函数,当该按钮被点击时,该函数就会执行。我在android开发的时候,称为给button增加监听和响应函数。

 

2.       右键点击控件,在出来的弹窗内选择“添加变量”,这是指给这个控件命名。此外,该控件是属于对话框这个类的一个属性。我们也可以利用对话框的实例的引用调用它。

 

3.       右键点击控件,在出来的弹窗内选择“类向导”,我们可以在这里面添加额外的消息事件,比如双击按钮时响应的函数。这里面也比较统揽全局查看所有控件的所有能产生消息的事件。

 

4.      Cdialog1Dlg::OnInitDialog()是当对话框刚产生的时候会执行的函数,可以将其作为这个程序的起点,一些初始化的内容可以写在里面。

 

 

对于多线程的制作

对我来说难度不大。也就是调用这个框架下的MFC而已,主要是以下几个函数:

1.创建一个线程

HANDLE m_hThread =CreateThread(NULL, 0, ThreadProcGetMacByWinpcap, this, 0, NULL);

其中重要的参数有:

ThreadProcGetMacByWinpcap:这是一个函数,就是线程开时候要执行的函数

This:this代表实例,由于我们有这个代码是写在对话框的这个类的实现函数里面,这个this就代表了目前我们这个对话框的实例(这个对象)。

2.暂停线程的运行:SuspendThread(m_hThread)

3.恢复线程的运行:ResumeThread(m_hThread)

4.停止线程:             TerminateThread(m_hThread,0)

 

 

在适当的消息函数内使用上述几个api,就可以比较好的控制另一个线程。虽然控制线程的方法有很多,但是我在本试验中只用到了那么几个。本次实验,我也就只用到了2个线程。一个是主线程,一个就是发包和收包的线程。书上写的用了3个线程,我实在是看不出用三个线程的必要性。如下图所示:

关于与自己的代码融合:

我觉得也就是处理一堆逻辑,没有什么值得叙述的。本次实验本来应该难点,求出本网段所有在线主机的mac地址:处理方法也就是连续发253个就行了。

 

Section III Test Cases and Results Analysis

获取用户名非常耗时,所以分两种情况:

1.       不获得用户名,一般在1秒之内即可。

2.   获取用户名的,每次去获得一次用户名需要耗时4秒左右。

Section IV Conclusion

1.觉得iphelper用起来方便,所以用iphelper来获取了IP地址,子网掩码,本机mac地址,网关。发包和收包我还是用winpcap。

 

2.网关的mac地址使用了GetIpNetTable2的方法:http://msdn.microsoft.com/en-us/library/windows/desktop/aa814420(v=vs.85).aspx

 

3.我始终没有能够用winpcap拿到正确的ip。进而拿不到对子网掩码。这部分我打算打linux系统下验证,到底怎么回事

//sockaddr_in*sin=(sockaddr_in*)&(Dev->addresses->addr);

//MessageBox(inet_ntoa(sin->sin_addr));

 

4.关键是不能用iphelper的方法来拿到发arp。必须用winpcap来发。winpcap里面必须要选择一个打开的设备。这一步我又跳不过,但是最终还是找到了办法。因为pcap_open得第一参数需要dev的name,仔细观察这一部分,发现和用iphelper得到的pAdapter->AdapterName。后面的一段字符是一样的。 将这后面一段一样的比较一部分,就知道打开的是哪个设备了。

代码中的321行起。虽然有点二,但是我还是很找办法啦!!

 

5.由于用winpcap的方法不能获得在线主机的主机名字。需要调用gethostbyaddr的方法。但是这个方法非常花时间。所以我又添加了一个checkbox,以确定是否显示主机名字,如果不显示就会非常的快.为什么这么慢?

 

6.我们目前写个程序的流程。无非就是:

首先,明确自己要做什么,想要什么。

其次,怎么要,就是调哪个api。接着,就是 了解api的参数&#x

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值