版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、MFC套接字编程上机指导一、 实验目的1. 熟悉AsyncSocket类的普通成员函数和事件成员函数;2. 理解Windows系统下,VC+的消息编程机制;3. 学会运用AsyncSocket类进行MFC套接字编程。二、 实验内容利用AsyncSocket类设计一个基于UDP协议传输数据的MFC应用程序,实现如图1中两个网络程序间的通信。 (a) (b)图1 a、b两个网程序间的通信三、 实验步骤1. 创建MFC工程1) 打开VC+6.0,点击“文件”“新建”,打开“新建”对话框,如图2所示。图2 “新建”对话框2) 选择,并在工程名称中输入工程名称“AsyncSocketEx”点击确定按钮,
2、打开“MFC应用程序向导 步骤1”对话框,如图3所示。图3 “MFC应用程序向导 步骤1”对话框3) 选择“您要创建的应用程序类型是:”中的“基本对话框D”,点击“下一步”按钮,打开“MFC应用程序向导 步骤2共4步”对话框,如图4所示。图4 “MFC应用程序向导 步骤2共4步”对话框4) 选择“您希望包含WOSA支持吗?”中的“Windows Sockets W”,点击“下一步”按钮,打开“MFC应用程序向导 步骤3共4步”对话框,如图5所示。图5 “MFC应用程序向导 步骤3共4步”对话框5) 点击“下一步”按钮,打开“MFC应用程序向导 步骤4共4步”对话框,如图6所示。图6 “MFC应
3、用程序向导 步骤4共4步”对话框6) 点击“完成”按钮,弹出“新建工程信息”对话框,如图7所示,点击“确定”按钮。这样一个新的MFC工程就已经创建好了,如图8所示。图7 “新建工程信息”对话框图8 新建的AsyncSocketEx工程示意图2. 向AsyncSocketEx工程中添加MFC控件本程序主要涉及到的控件有CStatic控件、CEdit控件、CButton控件、CIPAddress控件。CStatic控件在控件工具栏中显示为,它主要用于在对话框中显示静态的文本。CEdit控件在控件工具栏中显示为,它主要是用于向对话框输入数据以及动态的显示数据。CButton控件在控件工具栏中显示为,
4、它主要用于创建各种按钮。CIPAddress控件在控件工具栏中显示为,它主要是用于向程序输入IP地址以及获取IP地址。以上四种控件的详细信息及使用方法请参考MSDN。1) 删除默认的控件:将图8中默认对话框中的“TODO: 在这里设置对话控制。”静态控件、“确定”按钮、取消按钮删除。2) 添加静态控件CStatic控件:如图9中所示。注意:请添加自己的班级、学号和姓名。图9 添加静态控件CStatic控件3) 添加IP地址控件CIPAddress控件,该控件的图示为:1 添加本机IP地址控件:首先,选中本机IP地址控件,按回车键打开其属性框,弹出图10所示的对话框,将其ID改为“IDC_IPA
5、DDRESS_HOST”,之后关闭该对话框。然后,右击鼠标,选择“建立类向导”选项打开“MFC ClassWizard”对话框,选择“Member Variables”选项卡,选中IDC_IPADDRESS_HOST点击“Add Variable”按钮,添加类型为CIPAddressCtrl,变量名为m_IPAddress_Host的成员变量。如图11所示。点击“确定”按钮。图10 修改本机IP地址控件ID图11 添加成员变量m_IPAddress_Host2 以同样的方式添加添加远程IP地址控件,其ID设为IDC_IPADDRESS_REMOT,类型为CIPAddressCtrl,变量名为m
6、_IPAddress_Remot。4) 添加CEdit控件,所用方法同3)中的类似,空间的ID,类型,变量名如下表所示:表1 CEdit控件相关设置用途ID类型变量名本机端口编辑框IDC_EDT_HOSTPORTintm_HostPort远程端口编辑框IDC_EDT_REMOTPORTintm_RemotePort接收数据编辑框IDC_EDT_RECVFROMCStringm_ReceiveData发送数据编辑框IDC_EDT_SENDTOCStringm_SendData1 设置接收数据编辑框的属性值,如图12所示。图12 接收数据编辑框的属性设置2 设置发送数据编辑框的属性值,如图13所示
7、。图13 发送编辑框的属性设置5) 添加三个CButton控件,控件的用途、ID、标题如下表所示。表2 CButton控件相关设置用途ID标题初始化创建套接字对象IDC_BTN_INIT初始化发送数据IDC_BTN_SENDTO发送退出程序IDC_BTN_EXIT退出6) 设置发送按钮的属性值,在其属性对话框的样式中,将“缺省按钮”打勾,这样,发送按钮可以响应回车键。7) 添加完各种控件后的对话框如图14所示。图14 完成添加控件后的对话框8) 初始化IP地址控件(CIPAddress控件)的值1 点击按钮打开程序的类视图,如图15所示。图15 程序的类视图2 在类视图中,点击CAsyncSo
8、cketExDlg类前面的“+”号展开该类,双击该类中的成员函数打开成员函数,然后在“/ TODO: Add extra initialization here”下面添加如下代码:m_IPAddress_Host.SetAddress(ntohl(inet_addr("127.0.0.1");m_IPAddress_Remot.SetAddress(ntohl(inet_addr("127.0.0.1"); UpdateData(FALSE);/ 更新控件的值3 至此,可以运行查看IP控件的初始值了。3. 添加相关类及相关类的成员变量及函数在下面的实验步
9、骤中,一定要按照实验步骤的先后顺序添加,因为后面步骤的程序中可能要调用到前面步骤中添加的类、类的变量或者类的函数等。1) 添加CUDPSocket类及其成员1 添加CUDPSocket类:在类视图中,右击,选择“New Class”弹出新建类对话框,填入如图16中的信息,即将类名命名为CUDPSocket,基类Base class选择CAsyncSocket。点击“确定”按钮新建一个CUDPSocket。这时可以发现,在类视图中新增了。图16 新建类对话框2 添加成员变量m_fConnected:在类视图中,在上右击鼠标,选择“Add Member Variable”打开“添加成员变量”对话框
10、。在对话框中填入变量类型为bool,变量名称为m_fConnected,Access类型选择Public。如图17所示。该成员变量用来标识创建套接字是否成功,成功则置为true。在CUDPSocket类的构造函数CUDPSocket()中设置m_fConnected的初始值为false。图17 添加成员变量对话框3 添加成员函数BindLocatePC()a. 在类视图中,在上右击鼠标,选择“Add Member Function”打开“添加成员函数”对话框。在对话框中填入函数类型为bool,函数描述为BindLocatePC(DWORD m_LocateIP,int m_LocatePort
11、),选择Access类型为Public。如图18所示。该成员函数主要用来创建套接字。图18 添加成员函数对话框b. 在类视图中,双击下的打开BindLocatePC的函数体“bool CUDPSocket:BindLocatePC(DWORD m_LocateIP, int m_LocatePort)”,在起函数体中输入以下代码:in_addr tempAddr;CString buf;LPCTSTR p;CString m_erro;/获取本地IPtempAddr.S_un.S_addr=htonl(m_LocateIP);buf=inet_ntoa(tempAddr);p=(LPCTSTR
12、)buf;/绑定本地端口号和IPif (!Create(htons(m_LocatePort),SOCK_DGRAM,FD_READ|FD_WRITE,p)m_erro.Format("调用Create ()失败,错误代码为%d",GetLastError();AfxMessageBox(_T(m_erro);return false;m_fConnected=true; /设置标志位return true;4 添加成员函数SendToRemotePC()a. 在类视图中,在上右击鼠标,选择“Add Member Function”打开“添加成员函数”对话框。在对话框中填入
13、函数类型为bool,函数描述为SendToRemotePC(DWORD m_RemoteIP,int m_RemotePort,CString m_SendData),选择Access类型为Public。该成员函数主要用来发送数据。b. 在类视图中,双击下的打开SendToRemotePC的函数体“bool CUDPSocket:SendToRemotePC(DWORD m_RemoteIP, int m_RemotePort, CString m_SendData)”,在起函数体中输入以下代码:in_addr tempAddr;char send_buf1024;CString buf;LP
14、CTSTR p;CString m_erro;/发送数据if (m_fConnected)/获取远程IPtempAddr.S_un.S_addr=htonl(m_RemoteIP);buf=inet_ntoa(tempAddr);p=(LPCTSTR)buf;strcpy(send_buf,(char*)m_SendData.GetBuffer(m_SendData.GetLength();/发送数据int iByte=SendTo(send_buf,strlen(send_buf)+1,htons(m_RemotePort),p);/判断是否成功if(iByte>0)return tr
15、ue;elsem_erro.Format("调用SendTo()失败,错误代码为%d",GetLastError();AfxMessageBox(_T(m_erro);return false;return false;5 重载OnSend和OnReceive事件函数a. 在类视图中,在上右击鼠标,选择“Add Virtual Fnction”打开“New Virtual Override for class CUDPSocket”对话框。如图19所示,在对话框中选择“New Virtual Functions”一栏中的“OnSend”,点击“Add Handler”按钮即
16、将OnSend函数添加到CUDPSocket类中。同样地,选择“New Virtual Functions”一栏中的“OnReceive”,点击“Add Handler”按钮即将OnReceive函数添加到CUDPSocket类中。OnSend函数主要用来捕捉“写准备好”的事件通知的,即发送数据成功时,程序会跳到该函数执行。OnReceive函数主要用来捕捉“读准备好”的事件通知的,即有数据发送过来时,程序会跳到该函数执行。b. 注意,这两个重载的函数体中的程序代码需要在后面的步骤中添加,因为它们里面要调用对话框类中的函数还没有添加。图19 “New Virtual Override for
17、class CUDPSocket”对话框2) 添加CAsyncSocketExDlg类及其成员1 添加成员变量m_pSocket:a. 首先在“AsyncSocketExDlg.h”中添加头文件“#include "UDPSocket.h"”。之后,添加成员变量m_pSocket,方法同上,变量类型为“CUDPSocket*”,变量名称为m_pSocket,Access类型选择Public。b. 初始化m_pSocket:在类CAsyncSocketExDlg的构造函数CAsyncSocketExDlg(CWnd* pParent = NULL)的函数体中添加以下代码,使得
18、m_pSocket的初始值为“NULL”。m_pSocket = NULL;2 添加缓冲区最大值变量DATA_BUFFER_LENGHT:在AsyncSocketExDlg.cpp的引入头文件处添加如下代码:const int DATA_BUFFER_LENGHT = 1024;3 添加GetDialog()函数:a. 在类视图中,在上右击鼠标,选择“Add Member Function”打开“添加成员函数”对话框。在对话框中填入函数类型为“CAsyncSocketExDlg *”,函数描述为“static GetDialog()”,选择Access类型为Public。如图20所示,点击“确
19、定”按钮。该成员函数主要用来获取指向对话框类的指针。图20 添加成员函数GetDialog()b. 在类视图中,双击下的打开GetDialog的函数体,在其中添加如下代码:/获取对话框指针CAsyncSocketExDlg *pDl = (CAsyncSocketExDlg *)(AfxGetApp()->m_pMainWnd);if (!pDl)return NULL;return (pDl);4 添加OnReceive()函数:方法同上,其函数类型为“void”,函数描述为“OnReceive(int nErrorCode)”,选择Access类型为Public。点击“确定”按钮。然
20、后,在其函数体中添加如下代码,方法同上。char receive_bufDATA_BUFFER_LENGHT ;UINT m_rPort;CString m_rAddr ;CString m_erro;if (m_pSocket != NULL)/清空缓冲区memset(receive_buf, 0, sizeof(receive_buf);/接收消息int nBytes = m_pSocket->ReceiveFrom(receive_buf,DATA_BUFFER_LENGHT,m_rAddr,m_rPort,0);if (nBytes = SOCKET_ERROR) m_erro.
21、Format("调用ReceiveFrom函数失败,错误代码是%d",GetLastError();AfxMessageBox(_T(m_erro);return;/整理接收信息receive_bufnBytes = '0'strcat(receive_buf," From:") ;strcat(receive_buf,(char *)m_rAddr.GetBuffer(m_rAddr.GetLength() ;char buf100;itoa(ntohs(m_rPort),buf,10);strcat(receive_buf,"
22、; :") ;strcat(receive_buf,buf) ;m_ReceiveData+="rn"m_ReceiveData+=receive_buf;/刷新显示UpdateData(0);CEdit*pedit=(CEdit*)GetDlgItem(IDC_EDT_RECVFROM); int nline=pedit-> GetLineCount(); pedit-> LineScroll(nline-1);5 添加OnSend()函数:方法同上,其函数类型为“void”,函数描述为“OnSend(int nErrorCode)”,选择Acces
23、s类型为Public。点击“确定”按钮。然后,在其函数体中添加如下代码,方法同上。in_addr buf;DWORD m_RemoteIP;if (m_SendData.GetLength()=0)return;/将控件中的IP地址存储到m_RemoteIP中m_IPAddress_Remot.GetAddress(m_RemoteIP); buf.S_un.S_addr = htonl(m_RemoteIP);/将已发送的信息显示到接收数据编辑框m_ReceiveData+="rn"m_ReceiveData+=m_SendData;m_ReceiveData+=&quo
24、t; Have sent to "m_ReceiveData+=inet_ntoa(buf);m_SendData=""/刷新显示,使得有值变化的控件的值得以显示UpdateData(0);6 添加初始化按钮单击事件响应函数OnBtnInit():点击资源视图按钮,打开资源视图,如图21所示。双击图中的打开显示对话框的界面。双击“初始化”按钮,弹出“Add Member Function”对话框,如图22所示,从图中的信息可以看到,该函数名为OnBtnInit,作用的对象的ID是IDC_BTN_INIT,对应的消息是BN_CLICKED(即按钮被单击)。点击“OK
25、”按钮,在弹出的void CAsyncSocketExDlg:OnBtnInit()函数体中添加如下代码:图21 工程的资源视图图22 “Add Member Function”对话框DWORD m_LocalIP;/ 检查套接字是否为空if (m_pSocket != NULL)delete m_pSocket;m_pSocket = NULL;/ 创建新的套接字指针m_pSocket = new CUDPSocket();/从对话框获取数据UpdateData(1);m_IPAddress_Host.GetAddress(m_LocalIP);/绑定本地IPif (!m_pSocket-&
26、gt;BindLocatePC(m_LocalIP,m_HostPort) )AfxMessageBox(_T("Socket创建失败!");return; /使发送数据编辑框获得焦点CEdit*pedit=(CEdit*)GetDlgItem(IDC_EDT_SENDTO); pedit->SetFocus();7 添加退出按钮单击事件响应函数OnBtnExit ():方法与6中类似,双击“退出”按钮,打开“Add Member Function”对话框,如图23所示,从图中可以看出,该函数名为OnBtnExit,作用的对象的ID是IDC_BTN_EXIT,对应的消
27、息是BN_CLICKED(即按钮被单击)。点击“OK”按钮,在弹出的void CAsyncSocketExDlg:OnBtnExit()函数体中添加如下代码:图23 “Add Member Function”对话框/删除堆对象m_pSocketdelete(m_pSocket);/关闭对话框,退出系统EndDialog(0);8 完善类CUDPSocket的OnSend(int nErrorCode)重载函数:首先,在UDPSocket.cpp的最上端增加语句“#include "AsyncSocketExDlg.h"”,将AsyncSocketExDlg.h文件包含进来,
28、以便于使用CAsyncSocketExDlg类;然后,打开void CUDPSocket:OnSend(int nErrorCode)所处位置(方法同上),将函数内容修改为:void CUDPSocket:OnSend(int nErrorCode) / TODO: Add your specialized code here and/or call the base class/获取指向对话框的指针CAsyncSocketExDlg *pDl=CAsyncSocketExDlg:GetDialog();/调用对话框类下面的OnSend函数pDl->OnSend(nErrorCode);9 完善类CUDPSocket的OnReceive (int nErrorCode)重载函数:打开void CUDPSocket: OnReceive (int nErrorCode)所处位置(方法同上),将函数内容修改为:void CUDPSocket:OnReceive(int nErrorCode) / TODO: Add
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 食品加工行业安全生产工作总结
- 2024年标准合同履行确认保证合同版B版
- 2024年度大米产业链冷链物流合作协议3篇
- 语文高考押题专题二:语言运用
- 新娘父亲婚礼致辞
- 法学课程设计模拟法庭
- 放假留校学生安全责任保证书
- 2024年度员工敬业责任与职业发展通道建设合同3篇
- 文化艺术节活动的策划书(5篇)
- 护士个人工作调动申请书
- 《基层管理者职业素养与行为规范》考核试题及答案
- 《爆破理论基础》课件
- 期末测试题二(含答案)2024-2025学年译林版七年级英语上册
- 中国成人失眠诊断与治疗指南(2023版)解读
- 小儿咳嗽推拿治疗
- 产品质量知识培训课件
- 乳腺旋切手术
- 医护礼仪课件教学课件
- 2023年中国奥特莱斯行业白皮书
- 动态血压课件教学课件
- 八上必读名著《红星照耀中国》要点梳理与练习
评论
0/150
提交评论