《MFCSocket编程》PPT课件.ppt_第1页
《MFCSocket编程》PPT课件.ppt_第2页
《MFCSocket编程》PPT课件.ppt_第3页
《MFCSocket编程》PPT课件.ppt_第4页
《MFCSocket编程》PPT课件.ppt_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第2章MFCSocket编程,MFC及其Socket类,Socket类网络编程,Socket程序的互通,2.1MFC及其Socket类,2.1.1MFC简介MFC是很庞大的,以VisualC+6.0所带的MFC4.21为例,已经包含了多达上百个类、结构和接口!,2.1.1MFC简介,该层次结构可分为如下几种不同的类型:应用程序框架;图形绘制的绘制对象;文件服务;异常处理;结构,如Lists、Arrays和Maps;Internet服务;OLE2;数据库,2.1.2MFC中的Socket类,1CAsyncSocket类CAsyncSocket类是从MFC的根类CObject派生出来的,它在较低的级别上封装WindowsSocketAPI,因此类中包含的大部分成员函数和底层WinsockAPI函数有很多相似之处,有的甚至连名称和参数叫法都是相同或相近的。,2.1.2MFC中的Socket类,2CSocket类及其相关类(1)CSocket类。CSocket类是从CAsyncSocket类派生而来的,它继承了CAsyncSocket对WindowsSocketAPI的封装。与CAsyncSocket对象相比,CSocket对象代表了WindowsSocketAPI的更高一级的抽象化。,2.1.2MFC中的Socket类,(2)CSocket与CArchive、CSocketFile类的配合使用。使用CSocket类编写网络程序,既可以使用如CAsyncSocket类网络程序一样的Send和Receive函数来收发信息,也可以与CSocketFile类和CArchive类一起管理数据的发送和接收。,补充:CString与string,string为标准模板类(STL)定义的字符串类,在标准c+或者跨平台使用程序中建议使用。CString均是字符串模板类,在MFC或者ATL中实现,在使用mfc编程时建议使用CString。,2.2Socket类网络编程,2.2.1客户端服务器方式(C/S模式)1网络程序的通用体系结构客户端服务器方式所描述的是进程之间服务和被服务的关系。主机A运行客户端程序而主机B运行服务器程序。,两个人希望通过电话进行沟通,需要满足哪些条件?,1)对拨打电话的一方有什么要求?2)被拨打的电话有什么要求?3)如果被拨打的电话无人接听,怎么处理?4)对拨打电话和被拨打电话的人有什么语言上的要求?5)通话过程中,对物理线路有何要求?6)如何挂断电话?,基于TCP的网络应用程序通信过程,1)客户端需了解服务器的地址和端口2)服务器应用程序必须比客户端应用程序先启动,并在指定的ip地址和端口上执行监听操作。3)客户端发送数据时,服务端应用程序必须有足够的时间响应才能进行正常通信。4)双方必须采用相同协议5)通信过程中,物理网络保持畅通6)通信结束之前,客户端和服务端都可以中断连接,2.2.1客户端服务器方式(C/S模式),2最简单的Socket通信流程这里先来考虑一个只有客户端向服务方发信息的单向通信,并且也只有客户端会主动提出断开连接的最简单的情形(相反过程的原理是一样的),其双方Socket之间的关系如图所示。,2.2.1客户端服务器方式(C/S模式),由上面这个过程很容易得出对应的Socket通信流程。,2.2.2CAsyncSocket类编程基础,1对象分析若要实现上节分析的Socket通信流程共需要三个套接字对象:客户端一个(称为“客户Socket”);服务器两个(一个用于监听,称为“监听Socket”;另一个用于接收客户发来的信息,称为“服务Socket”)。这三个套接字对象对应三个Socket类,都继承自CAsyncSocket,分别为它们取名如表2.2所示(表中的类名也是后面程序中需要使用的)。,案例:使用CAsyncSocket类实现网络通信,1.工程设计1)分别做客户端和服务端客户端:ChatClient工程服务端:ChatServer工程,案例:使用CAsyncSocket类实现网络通信,2界面设计-客户端,案例:使用CAsyncSocket类实现网络通信,2界面设计-服务端,案例:使用CAsyncSocket类实现网络通信,3.给各个必要控件添加变量客户端服务端,案例:使用CAsyncSocket类实现网络通信,4.添加相关类并增加对象客户端CClientSocket:其基类为:CAsyncSocket服务端ClistenSocket:其基类为:CAsyncSocketCServerSocket:其基类为:CAsyncSocket,案例:使用CAsyncSocket类实现网络通信,4.添加相关类并增加对象客户端CClientSocketm_ClientSocket;服务端CListenSocketm_ListenSocket;CServerSocketm_ServerSocket;,案例:使用CAsyncSocket类实现网络通信,5.编写详细代码1)服务器端创建监听socket。编程思路:获取对话框上输入的IP地址和端口号使用Create函数创建一个套接字使用Listen函数设置套接字开始监听在列表框中显示“开始监听”字样,案例:使用CAsyncSocket类实现网络通信,Create函数使用方法:CAsyncSocket类的对象名.Create(端口号,套接字类型,事件类型,ip地址),其中:套接字类型可取值为SOCK_STREAM或SOCK_DGRAM,分别指流式套接字和数据报套接字。事件类型:可取值为FD_READ,FD_WRITE,FD_OOB,FD_ACCEPT,FD_CONNECT,FD_CLOSE。,案例:使用CAsyncSocket类实现网络通信,Listen函数使用方法:CAsyncSocket类的对象名.Listen(挂起的连接队列可以增大到的最大长度),参数取值范围为1-5,案例:使用CAsyncSocket类实现网络通信,列表框中增加一行字符串:列表框绑定的control类别变量的名称.AddString(“所要增加的字符串”);,案例:使用CAsyncSocket类实现网络通信,#includeListenSocket.h#includeServerSocket.h“/下面这两行放在CServerSocketDlg类的public部分CListenSocketm_ListenSocket;CServerSocketm_ServerSocket;,案例:使用CAsyncSocket类实现网络通信,voidCChatServerDlg:OnBTNStartlisten()BYTEnFild4;CStringsIP,sP;UpdateData();m_ServerIp.GetAddress(nFild0,nFild1,nFild2,nFild3);sIP.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3);sP.Format(%d,m_sPort);m_ListenSocket.Create(m_sPort,1,FD_ACCEPT,sIP);m_ListenSocket.Listen(1);m_ListWords.AddString(在+sIP+:+sP+监听.);,案例:使用CAsyncSocket类实现网络通信,5.编写详细代码2)客户端创建客户socket并发起连接。编程思路:获取对话框上输入的IP地址和端口号使用Create函数创建一个套接字使用Connect函数实现与服务器的连接如果成功,在列表框中显示“连接成功”字样,案例:使用CAsyncSocket类实现网络通信,Connect函数使用方法CAsyncSocket类的对象名.Connect(ip地址,端口号);,案例:使用CAsyncSocket类实现网络通信,voidCChatClientDlg:OnBTNConnect()BYTEnFild4;CStringsIP;UpdateData();m_ServerIp.GetAddress(nFild0,nFild1,nFild2,nFild3);sIP.Format(%d.%d.%d.%d,nFild0,nFild1,nFild2,nFild3);m_ClientSocket.Create();m_ClientSocket.Connect(sIP,m_sPort);,添加CClientSocket的OnConnect虚函数,添加CClientSocket的OnConnect虚函数,添加CClientSocket的OnConnect虚函数,voidCClientSocket:OnConnect(intnErrorCode)if(nErrorCode)AfxMessageBox(连接失败!请重试!);return;(CChatClientDlg*)(AfxGetApp()-m_pMainWnd)-m_ListWords.AddString(连接成功.);,案例:使用CAsyncSocket类实现网络通信,5.编写详细代码3)客户端连接服务端成功后发送信息。编程思路:获取对话框上输入的信息使用Send函数实现信息的发送在列表框中显示发送的信息内容,voidCChatClientDlg:OnBTNSend()UpdateData();m_ClientSocket.Send(m_sWords,m_sWords.GetLength();m_ListWords.AddString(发送:+m_sWords);GetDlgItem(IDC_MESSAGE)-SetWindowText();,案例:使用CAsyncSocket类实现网络通信,5.编写详细代码4)服务端socket等待客户发来的消息并接受。编程思路:接收客户端的连接请求接收客户端发来的信息在列表框中显示相关信息,具体实现,1)添加CListenSocket的OnAccept的虚函数实现接收客户端的连接请求2)添加CServerSocket的OnReceive的虚函数实现接收客户端发来的信息,案例:使用CAsyncSocket类实现网络通信,关闭连接和退出。请写出双向通信的程序。,2.2.3CAsyncSocket类程序的指针实现,1非指针程序的机制缺陷前面的程序存在以下缺陷:1)Socket的创建、使用和销毁不灵活。2)程序代码分散。如服务端就有CListenSocket和CServerSocket两个类的基类是CAsyncSocket。,2.2.3CAsyncSocket类程序的指针实现,1非指针程序的机制缺陷前面的程序存在以下缺陷:3)代码可读性差。如果在Socket的代码中要访问和控制主对话框界面上的控件,则需要运用AfxGetApp()全局函数获取主窗口CWinApp类指针,这意味着每一个在Socket中访问到主界面控件的语句前都要写上冗长的类似下面的这句代码:(CChatClientDlg*)(AfxGetApp()-m_pMainWnd)-,2.2.3CAsyncSocket类程序的指针实现,2用对话框指针机制实现的Socket程序(1)建立工程。分别创建客户端和服务器工程,客户和服务器工程中各添加一个基于CAsyncSocket类的MySocket类,这个类是用来为通信双方动态生成Socket对象服务的。,补充技巧,因为界面与原来的两个工程的界面一样,可以在原来工程的基础上进行修改。修改步骤如下。1)找到类所涉及的文件并删除(包含.h和.cpp文件)2)删除扩展名为clw的文件3)打开扩展名为dsp的文件(文本编辑工具),删除和要删除的类相关的条目4)使用vc打开dsw文件,然后打开建立类向导,点确定5)重新编译文件,把相关代码删除6)如还有错,可把debug文件夹下的内容删除,全部重建即可,关于指针,CChatClientDlg*m_dlg;CChatClientDlgm_dlg;,CAboutDlgdlg;dlg.DoModal();,CAboutDlg*dlg;dlg=newCAboutDlg();dlg-DoModal();,指针形式实现,关于指针,1:如何对指针进行初始化int*p;请写出对应的给指针初始化语句;,程序结构分析,主对话框类和mysocket类主对话框中实现基本的按钮消息等功能Mysocket类中需重载对应的虚函数。,2.2.3CAsyncSocket类程序的指针实现,(2)用对话框指针机制组织新程序的框架。,在MySocket.h中添加如下代码:classCChatClientDlg;/为了能够在MySocket类中定义主对话框类指针,首先对主对话框类进行前导声明CChatClientDlg*m_dlg;/在MySocket类中定义一个主对话框指针voidGetDlg(CChatClientDlg*dlg);/获取主对话框指针的函数,2.2.3CAsyncSocket类程序的指针实现,在ChatClientDlg.h中添加如下代码:#includeMySocket.hMySocket*m_ClientSocket;voidOnReceive();voidOnClose();voidOnConnect();voidSocketReset();,2.2.3CAsyncSocket类程序的指针实现,BOOLCChatClientDlg:OnInitDialog().m_ClientSocket=NULL;/MySocket类对象指针初始化为空returnTRUE;,2.2.3CAsyncSocket类程序的指针实现,写出已声明的三个函数OnClose()、OnConnect()、OnReceive()的函数体,同时实现SocketReset()函数voidCChatClientDlg:SocketReset()if(m_ClientSocket!=NULL)deletem_ClientSocket;m_ClientSocket=NULL;,2.2.3CAsyncSocket类程序的指针实现,在MySocket.cpp中实现获取主对话框指针的GetDlg()函数,并通过指针引用主对话框程序代码中的网络事件处理函数#includeChatClientDlg.h“voidMySocket:GetDlg(CChatClientDlg*dlg)/获得窗口界面的指针m_dlg=dlg;voidMySocket:OnClose(intnErrorCode)m_dlg-OnClose();,2.2.3CAsyncSocket类程序的指针实现,voidMySocket:OnConnect(intnErrorCode)m_dlg-OnConnect();voidMySocket:OnReceive(intnErrorCode)m_dlg-OnReceive();,2.2.3CAsyncSocket类程序的指针实现,(3)代码的复制、修改。修改前面所写代码如下。“连接”按钮的消息处理函数码如下:m_ClientSocket=newMySocket;m_ClientSocket-GetDlg(this);m_ClientSocket-Create();/创建客户端Socketm_ClientSocket-Connect(sIP,m_sPort);/发起连接请求,2.2.3CAsyncSocket类程序的指针实现,“断开”:m_ClientSocket-Close();/关闭客户端SocketSocketReset();/避免指针悬空“发送”按钮事件过程代码如下:UpdateData();m_ClientSocket-Send(m_sWords,m_sWords.GetLength();/向服务器发送信息,2.2.3CAsyncSocket类程序的指针实现,因为CAsyncSocket是异步操作的Socket类,它在使用Connect方法发起连接请求后,无论连接成功与否都立即返回,我们只能根据OnConnect事件的错误码nErrorCode来判断连接是否成功,而若要获取这个错误码值,则必须进入响应OnConnect事件的处理过程,这就决定了程序员自己在主对话框中定义的函数OnConnect()的代码必须有一部分置于Socket本身的OnConnect响应函数中:,2.2.3CAsyncSocket类程序的指针实现,voidMySocket:OnConnect(intnErrorCode)/确认客户端是否成功连接到服务器if(nErrorCode)AfxMessageBox(连接失败,请您重试!);return;m_dlg-OnConnect();CAsyncSocket:OnConnect(nErrorCode);,2.2.3CAsyncSocket类程序的指针实现,采用与客户端类似的方法,请同学们课下完成.,2.2.4CSocket类编程,编程步骤:1、构造一个CSocket对象。2、使用这个对象的Create()成员函数产生一个socket对象。3、如果是客户方套接字,则调用CAsyncSocketConnect()函数与服务方套接字连接;如果是服务方套接字,则调用Listen()开始监听来自客户方的连接请求,收到连接请求后,调用Accept()函数接受请求,建立连接。请注意Accept()成员函数需要一个新的并且为空的CSocket对象作为它的参数。,2.2.4CSocket类编程,编程步骤:4、产生一个CSocketFile对象,并把它与CSocket对象关联起来。5、为接收和发送数据各产生一个CArchive对象,把它们与CSocketFile对象关联起来。切记CArchive是不能和数据报套接字一起工作的。6、使用CArchive对象的Read()、Write()等函数在客户与服务方传送数据。7、通讯完毕后,销毁CArchive、CSocketFile和CSocket对象。,2.2.4CSocket类编程,1建立工程分别创建客户端和服务器工程,设置和前两节的程序完全一样,创建完成后分别在双方工程中各添加一个基于CSocket基类的MySocket类。,2.2.4CSocket类编程,ChatClientDlg中SocketReset()OnReceive()OnClose(),MySocket中继承自CSocketonReceive(intnErrorCode)onClose(intnErrorCode)自定义函数:GetDlg(CChatClientDlg*dlg),MySocket*m_ClientSocket;/客户端套接字指针CArchive*m_archiveIn;/收到的信息的存储文件CArchive*m_archiveOut;/发送的信息的存储文件CSocketFile*m_socketfile;/用于发送和接受数据的缓冲区CStringm_Input;/接收信息用变量,1-建立程序框架,1)头文件引入及自定义函数声明在MySocket.h中#includeAfxsock.hclassCChatClientDlg;CChatClientDlg*m_dlg;voidGetDlg(CChatClientDlg*dlg);,1-建立程序框架,1)头文件引入及自定义函数声明在ChatClientDlg.h中,#includeMySocket.hMySocket*m_ClientSocket;/客户端套接字指针CArchive*m_archiveIn;/收到的信息的存储文件CArchive*m_archiveOut;/发送的信息的存储文件CSocketFile*m_socketfile;/用于发送和接收数据的缓冲区voidOnReceive();voidOnClose();voidSocketReset();CStringm_Input;,2-相关变量初始化,m_ClientSocket=NULL;m_archiveIn=NULL;m_archiveOut=NULL;m_socketfile=NULL;,思考,此初始化代码应该放在什么位置?,CChatClientDlg:OnInitDialog(),3-相关函数的实现,1)CChatClientDlg:SocketReset()/回收所有指针变量占用的存储空间;并重新初始化所有指针变量为NULL。,请同学们写出代码,3-相关函数的实现,2)CChatClientDlg:OnReceive()/接收信息处理函数,CArchive以一段内存空间作为临时数据存储地,对CArchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整理后的数据读写到指定的存储媒质。,3-相关函数的实现,2)CChatClientDlg:OnReceive()提取缓冲区中的值强制保持在存档缓冲区的任何数据都将写入文件。设置列表框中的内容,3-相关函数的实现,3)CChatClientDlg:OnClose()设置列表框中的信息重置socket,3-相关函数的实现,4)MySocket:GetDlg(CChatClientDlg*dlg)/获取到主对话框并赋值给本类中的数据成员CChatClientDlg*m_dlg;,请同学们写出代码,3-相关函数的实现,5)MySocket:OnReceive(intnErrorCode)/继承CSocket类,调用主对话框类的OnReceive()函数AsyncSelect(事件类型);选择感兴趣的事件。,3-相关函数的实现,6)MySocket:OnClose(intnErrorCode)/继承自CSocket类,调用主对话框类的OnClose()函数,4-各个按钮的功能详细实现,1)连接按钮AfxSocketInit();必须调用,对WindowsSockets进行初始化创建客户端socket发起连接,如果连接失败,则提示,否则转入显示连接成功字样,并给所需指针分配存储空间。,CArchive(CFile*pFile,UINTnMode)接收数据:CArchive:load发送数据:CArchive:storeCSocketFile(CSocket*pSocket,BOOLbArchiveCompatible=TRU

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论