(精品)MFC网络编程.ppt

上传人:s****8 文档编号:68125585 上传时间:2022-12-27 格式:PPT 页数:64 大小:942.50KB
返回 下载 相关 举报
(精品)MFC网络编程.ppt_第1页
第1页 / 共64页
(精品)MFC网络编程.ppt_第2页
第2页 / 共64页
点击查看更多>>
资源描述

《(精品)MFC网络编程.ppt》由会员分享,可在线阅读,更多相关《(精品)MFC网络编程.ppt(64页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、MFC WinSock类的编程类的编程为简化套接字网络编程,更方便地利用Windows的消息驱动机制,微软的基础类库(Microsoft Foundation Class Libary,简称MFC),提供了两个套接字类,在不同的层次上对Windows Socket API函数进行了封装,为编写Windows Socket网络通信程序,提供了两种编程模式。CAsyncSocket类,在很低的层次上对WindowsSocketsAPI进行了封装。它的成员函数和WindowsSocketsAPI的函数调用直接对应。一个CAsyncSocket对象代表了一个Windows套接字。它是网络通信的端点。除

2、了把套接字封装成C+的面向对象的形式供程序员使用以外,这个类唯一所增加的抽象就是将那些与套接字相关的Windows消息变为CAsyncSocket类的回调函数。CSocket类,从CAsyncSocket类派生,是对WindowsSocketsAPI的 高 级 封 装。CSocket类继承了CAsyncSocket类的许多成员函数,用法一致。CSocket类的高级表现在三个方面:(1)CSocket结合archive类来使用套接字。(2)CSocket管理了通信的许多方面,如字节顺序问题和字符串转换问题。(3)CSocket类为Windows消息的后台处理提供了阻塞的工作模式。这两个类提供了事

3、件处理函数,编程者通过对事件处理函数进行重载,可方便地对套接字发送数据、接收数据等事件进行处理。同时,可以结合MFC的其它类来使用这两个套接字类,并利用MFC的各种可视化向导,从而大大简化了编程。在MFC中,有一个名为afxSock.h的包含文件,在这个文件中定义了CAsyncSocket,CSocket,和CSocketFile这三个套接字类。CasyncSocket类类CAsyncSocket类从Cobject类派生而来,如图1所示:图1CAsyncSocket类的派生关系 创建创建CasyncSocket类对象类对象 本书将CAsyncSocket类对象称为异步套接字对象。创建异步套接字

4、对象一般分为两个步骤,首先构造一个CAsyncSocket对象,再创建该对象的底层的SOCKET句柄。1创建空的异步套接字对象创建空的异步套接字对象 通过调用CAsyncSocket类的构造函数,创建一个新的空CAsyncSocket类套接字对象,构造函数不带参数。然后必须调用它的Create成员函数,来创建底层的套接字数据结构,并绑定它的地址。有两种使用方法,会在不同的位置创建。(1)如:CAsyncSocketaa;aa.Create(。);(2)如:CAsyncSocket*Pa;Pa=newCAsyncSocket;Pa-Create(。);2创建异步套接字对象的底层套接字句柄创建异步

5、套接字对象的底层套接字句柄通过调用CAsyncSocket类的Create()成员函数,创建该对象的底层套接字句柄,决定套接字对象的具体特性。调用格式为:BOOLCreate(UINTnSocketPort=0,IntnSocketType=SOCK_STREAM,Long Ievent=FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,LPCTSTRlpszSocketAddress=NULL);举例:创建一个使用27端口的流式异步套接字对象。CAsyncSocket*pSocket=newCAsyncSocket;intnPort=

6、27;pSocket-Create(nPort,SOCK_STREAM);关于关于CAsyncSocket类可以接受并处理的消息事件类可以接受并处理的消息事件1六种套接字相关的事件与通知消息六种套接字相关的事件与通知消息参数Ievent可以选用的六个符号常量是在winsock.h文件中定义的。#defineFD_READ0 x01#defineFD_WRITE0 x02#defineFD_OOB0 x04#defineFD_ACCEPT0 x08#defineFD_CONNECT0 x10#defineFD_CLOSE0 x20 他们代表MFC套接字对象可以接受并处理的六种网络事件,当事件发生

7、时,套接字对象会收到相应的通知消息,并自动执行套接字对象响应的事件处理函数。(1)FD_READ事件通知:通知有数据可读。(2)FD_WRITE事件通知:通知可以写数据。(3)FD_ACCEPT事件通知:通知监听套接字有连接请求可以接受。(4)FD_CONNECT事件通知:通知请求连接的套接字,连接的要求已被处理。(5)FD_CLOSE事件通知:通知套接字已关闭。(6)FD_OOB事件通知:通知将有带外数据到达。2MFC框架对于六个网络事件的处理框架对于六个网络事件的处理当上述的网络事件发生时,MFC框架作何处理呢?按照Windows的消息驱动机制,MFC框架应当把消息发送给相应的套接字对象,

8、并调用作为该对象成员函数的事件处理函数。事件与处理函数是一一映射的。在afxSock.h文件中的CAsyncSocket类的声明中,定义了与这六个网络事件对应的事件处理函数。virtualvoidOnReceive(intnErrorCode);对应FD_READ事件virtualvoidOnSend(intnErrorCode);对应FD_WRITE事件virtualvoidOnAccept(intnErrorCode);对应FD_ACCEPT事件virtualvoidOnConnect(intnErrorCode);对应FD_CONNECT事件virtualvoidOnClose(intn

9、ErrorCode);对应FD_CLOSE事件virtualvoidOnOutOfBandData(intnErrorCode);对应FD_OOB事件 当某个网络事件发生时,MFC框架会自动调用套接字对象的对应的事件处理函数。这就相当给了套接字对象一个通知,告诉它某个重要的事件已经发生。所以也称之为套接字类的通知函数(notificationfunctions)或回调函数(callbackfunctions)。3重载套接字对象的回调函数重载套接字对象的回调函数如果你从CAsyncSocket类派生了自己的套接字类,你必须重载你的应用程序所感兴趣的那些网络事件所对应的通知函数。MFC框架自动调用

10、通知函数,使得你可以在套接字被通知的时候来优化套接字的行为。客户端套接字对象请求连接到服务器端客户端套接字对象请求连接到服务器端 在服务器端套接字对象已经进入监听状态之 后,客 户 应 用 程 序 可 以 调 用CAsyncSocket类的Connect()成员函数,向服务器发出一个连接请求,格式一:BOOL Connect(LPCTSTRlpszHostAddress,UINTnHostPort);格 式 二:BOOL Connect(const SOCKADDR*lpSockAddr,intnSockAddrLen);如 果 调 用 成 功 或 者 发 生 了WSAEWOULDBLOCK错

11、误,当调用结束返回时,都会发生FD_CONNECT事件,MFC框架会自动调用客户端套接字的OnConnect()事件处理函数,并将错误代码作为参数传送给它。它的原型调用格式如下,virtualvoidOnConnect(intnErrorCode);服务器接受客户机的连接请求服务器接受客户机的连接请求在服务器端,使用CAsyncSocket流式套接字对象,一般按照以下步骤来接收客户端套接字对象的连接请求。(1)服务器应用程序必须首先创建一个CAsyncSocket流式套接字对象,并调用它的Create成员函数创建底层套接字句柄。这个套接字对象专门用来监听来自客户机的连接请求,所以称它为监听套接

12、字对象。(2)调用监听套接字对象的Listen成员函数,使监听套接字对象开始监听来自客户端的连接请求。此函数的调用格式是:BOOLListen(intnConnectionBacklog=5);当Listen函数确认并接纳了一个来自客户端的连接请求后,会触发FD_ACCEPT事件,监听套接字会收到通知,表示监听套接子已经接纳了一个客户的连接请求,MFC框架会自动调用监听套接字的OnAccept事件处理函数,它的原型调用格式如下,virtualvoidOnAccept(intnErrorCode);编程者一般应重载此函数,在其中调用监听套接字对象的Accept函数,来接收客户端的连接请求。(3)

13、创建一个新的空的套接字对象,不需要使用它的Create函数来创建底层套接字句柄。这个套接字专门用来与客户端连接,并进行数据的传输。一般称它为连接套接字,并作为参数传递给下一步的Accept成员函数。(4)调用监听套接字对象的Accept成员函数,调用格式为:virtualBOOLAccept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpSockAddr=NULL,int*lpSockAddrLen=NULL);发送与接收流式数据发送与接收流式数据当服务器和客户机建立了连接以后,就可以在服务器端的连接套接字对象和客户端的套接字对象之间传输数据了。对于流式套接

14、字对象,使用CAsyncSocket类的Send成员函数向流式套接字发送数据,使用Receive成员函数从流式套接字接收数据。1用用Send成员函数发送数据成员函数发送数据格式:virtualintSend(constvoid*lpBuf,intnBufLen,intnFlags=0);对于一个CAsyncSocket套接字对象,当它的发送缓冲区腾空时,会激发FD_WRITE事件,套接字会得到通知,MFC框架会自动调用这个套接字对象的OnSend事件处理函数。一般编程者会重载这个函数,在其中调用Send成员函数来发送数据。2用用Receive成员函数接收数据成员函数接收数据格式:Virtual

15、intReceive(Void*lpBuf,IntnBufLen,IntnFlags=0);对于一个CAsyncSocket套接字对象,当有数据到达它的接收队列时,会激发FD_READ事件,套接字会得到已经有数据到达的通知,MFC框架会自动调用这个套接字对象的OnReceive事件处理函数。一般编程者会重载这个函数,在其中调用Receive成员函数来接收数据。在应用程序将数据取走之前,套接字接收的数据将一直保留在套接字的缓冲区中。关闭套接字关闭套接字1使使用用CAsyncSocket类类的的Close成成员员函函数数格式:virtualvoidClose();2 使使 用用 CAsyncSoc

16、ket类类 的的 ShutDown()成员函数成员函数 使用CAsyncSocket类的ShutDown()成员函数,可以选择关闭套接字的方式。将套接字置为不能发送数据,或不能接收数据,或二者均不能的状态。格式:BOOLShutDown(intnHow=sends);错误处理错误处理 一般说来,调用CAsyncSocket对象的成员函数后,返回一个逻辑型的值,如果成员函数执行成功,返回TRUE;如果失败,返回FALSE。究竟是什么原因造成错误呢?这时,可以进一步调用CAsyncSocket对象的GetLastError()成员函数,来获取更详细的错误代码,并进行相应的处理。格式:statici

17、ntGetLastError();返回值是一个错误码,针对刚刚执行的CAsyncSocket成员函数。其它的成员函数其它的成员函数1关于套接字属性的函数关于套接字属性的函数要设置底层套接字对象的属性,可以调用SetSocketOpt()成员函数;要获取套接字的设置信息,可调用GetSocketOpt()成员函数;要控制套接字的工作模式,可调用IOCtl()成员函数,选择合适的参数,可以将套接字设置在阻塞模式(Blockingmode)下工作。2发送和接收数据发送和接收数据如果创建的是数据报类型的套接字,用SendTo()成员函数来向指定的地址发送数据,事先不需要建立发送端和接收端之间的连接,用

18、ReceiveFrom()成员函数可以从某个指定的网络地址接收数据。发送数据SendTo的调用格式,有两种重载的形式,区别在于参数不同:intSendTo(constvoid*lpBuf,intnBufLen,UINTnHostPort,LPCTSTRlpszHostAddress=NULL,intnFlags=0);intSendTo(constvoid*lpBuf,intnBufLen,constSOCKADDR*lpSockAddr,intnSockAddrLen,intnFlags=0);应用实例是一个简单的聊天室程序,采用客户/服务器模式,分为客户端程序和服务器端程序。由于服务器只能

19、支持一个客户,实际是一个点对点通信的程序。客户端程序和服务器程序通过网络交换聊天的字符串内容,并在窗口的列表框中显示。CAsyncSocket类的应用实例类的应用实例实例程序的技术要点是:如何从CAsyncSocket类派生出自己的WinSock类。理解WinSock类与应用程序框架的关系。重点学习流式套接字对象的使用。处理网络事件的方法。创建客户端应用程序创建客户端应用程序1使用使用MFC AppWizard创建客户端应用程序框架。创建客户端应用程序框架。(1)在New对话框中,选择Projects卡,如图4所示。从左边的列表框中选择MFCAppWizard(exe)条目,在右边的Proje

20、ctName处填入工程名Talkc,在Location处选定存放此工程的目录。然后点击OK按钮。(2)出现MFCAppWizard设置的第一步对话框(MFCAppWizardStep1),如图5所示。从中选择Dialogbased的应用程序类型,语言支持选择中文(中国),使此工程能够正确地进行中文的输入、输出、显示及处理。然后点击NEXT按钮。(3)出现MFCAppWizard设置的第二步对话框(MFCAppWizardsStep2of4),如图6所示,在WindowsSockets复选框上打上选择标记,表示应用程序将支持WinSock套接字。接受其它的默认设置。跳过后面的步骤,直接点击Fin

21、sh按钮。(4)出现新工程信息对话框(NewProjectInformation),说明了所创建的骨架工程的有关信息。如图7所示。从中可以看出,所创建的程序是一个基于对话框的Win32应用程序,将自动创建两个类,应用程序类CTalkcApp,对应的文件是talkc.h和talkc.cpp;对话框类CTalkcDlg,对应的文件是talkcDlg.h和talkcDlg.cpp。支持WindowsSocket,使用共享的DLL实现MFC42.DLL。2为对话框界面添加控件对象为对话框界面添加控件对象在创建了应用程序骨架之后,可以布置程序的主对话框。在MFC界面左方的工作区(workspace)中选

22、择resourceView卡,从中选择Dialog,双击IDD_TALKC_DIALOG,右边会出现对话框,左边会出现控件面板,利用控件面板可以方便地在程序的主对话框界面中添加相应的可视控件对象,如图8所示。图8 在主对话框中添加控件 完成的对话框如图9所示,然后按照表2修改控件的属性。图9 Talkc程序的主对话框 表2 Talkc程序主对话框中的控件属性表 控件类型控件IDCaption静态文本statictextIDC_STATIC_SERVNAME服务器名称静态文本statictextIDC_STATIC_SERVPORT服务器端口静态文本statictextIDC_STATIC_MS

23、G消息静态文本statictextIDC_STATIC_SENT发送的消息静态文本statictextIDC_STATIC_RECEIVED接收的消息编辑框editboxIDC_EDIT_SERVNAME编辑框editboxIDC_EDIT_SERVPORT编辑框editboxIDC_EDIT_MSG命令按钮buttonIDC_BUTTON_CONNECT连接命令按钮buttonIDC_BUTTON_CLOSE断开命令按钮buttonIDOK发送列表框listboxIDC_LIST_SENT列表框listboxIDC_LIST_RECEIVED3为对话框中的控件对象定义相应的成员变量为对话框中

24、的控件对象定义相应的成员变量在窗口菜单中点查看/建立类向导,进入类向导(ClassWizard)对话框,如图10。选择成员变量卡(MemberVariables),用类向导为对话框中的控件对象定义相应的成员变量。确认ClassName是CTalkcDlg,在左边的列表框中选择一个控件,然后点“AddVariable”按钮,会弹出”AddMemberVariable”对话框,如图11所示,然后按照表3输入即可。图11 增加控件成员变量的对话框 表3客户端程序对话框中的控件对象对应的成员变量 控件IDControlIDs变量名称MemberVariableName变量类别Category变量类型V

25、ariableTypeIDC_BUTTON_CONNECTm_btnConnectControlCButtonIDC_EDIT_SERVNAMEm_strServNameValueCStringIDC_EDIT_SERVPORTm_strServPortValueintIDC_EDIT_MSGm_strMsgValueCStringIDC_LIST_SENTm_listSentControlCListBoxIDC_LIST_RECEIVEDm_listRecetvedControlCListBox4创建从创建从CAsyncSocket类继承的派生类类继承的派生类(1)为了能够捕获并响应sock

26、et事件,应创建用户自己的套接字类,它应当从CAsyncSocket类派生,还能将套接字事件传递给对话框,以便执行用户自己的事件处理函数。选择菜单“插入/新建类”,进入“NewClass”对话框,如图12所示。图12添加自己的套接字类 选择或输入以下信息:ClassType:选择MFCClassClassInfoumation下的Name:输入CMySocketClassInfoumation下 的 Baseclass:选 择CAsyncSocket点击“OK”按钮,系统会自动生成CMySocket类对应的包含文件MySocket.h和MySocket.cpp文件,在VC界面的ClassVie

27、w中就可以看到这个类。(2)利用类向导ClassWizard为这个套接字类添加响应消息的事件处理成员函数。点菜单View/ClassWizard.,进入类向导对话框,选择MessageMaps(消息映射)卡,确认Classname是CMySocket,从Messages(消息)栏中选择事件消息,然后点击AddFunction按钮,就会看到在MemberFunction栏中添加了相应的事件处理函数。如图13所示,此程序中需要添加OnConnect,OnClose和OnReceive三个函数。这一步会在CMySocket类的MySocket.h中自动生成这些函数的声明,在MySocket.cpp中

28、生成这些函数的框架,以及消息映射的相关代码。可参看后面的程序清单。图13为套接字类添加响应消息的事件处理成员函数(3)为套接字类添加一般的成员函数和成员变量在VC+的界面中,在工作区窗口选择ClassView卡,用右键单击CMySocket类,会弹出快捷菜单,选择其中的AddMember Function 可以为该类添加成员函数;选择AddMemberVariable可以为该类添加成员变量。如图14所示。图15和图16是添加操作的对话框。对这个套接字类,添加一个私有的成员变量,是一个对话框类的指针。private:CTalkcDlg*m_pDlg;图15为套接字类添加一般的成员变量 再添加一个

29、成员函数:void SetParent(CTalkcDlg*pDlg);图16为套接字类添加一般的成员函数这一步同样会在MySocket.h中生成变量或函数的声明,在MySocket.cpp中生成函数的框架代码。如果熟悉的话,这一步的代码也可以直接手工添加。(4)手工添加其他代码在VC+的界面中,在工作区窗口选择FileView卡,双击要编辑的文件,在右面的窗口中就会展示该文件的代码,可以编辑添加。对于MySocket.h,应在文件开头,添加对于此应用程序对话框类的声明。classCTalkcDlg;对于MySocket.cpp,有四处添加:应在文件开头,添加包含文件说明。这是因为此套接字类用

30、到了对话框类的变量。#include“TalkcDlg.h”在构造函数中,添加对于对话框指针成员变量的初始化代码:CMySocket:CMySocket()m_pDlg=NULL;在析构函数中,添加对于对话框指针成员变量的初始化代码:CMySocket:CMySocket()m_pDlg=NULL;为成员函数setParent和事件处理函数OnConnect,OnClose和OnReceive添加代码。详见后面的程序清单。5为对话框类添加控件对象事件的响应函数为对话框类添加控件对象事件的响应函数按照表4,用类向导(ClassWizard)为对话框中的控件对象添加事件响应函数。主要是对于三个按钮

31、的单击事件的处理函数,如图17所示。其他函数是原有的。表4为对话框中的控件对象添加事件响应函数 控件类型对象标识ObjectIDs消息Messages函数Memberfunctions命令按钮IDC_BUTTON_CLOSEBN_CLICKEDOnButtonClose命令按钮IDC_BUTTON_CONNECTBN_CLICKEDOnButtonConnect命令按钮IDOKBN_CLICKEDOnSendMsg图17为对话框类添加控件事件的处理函数这一步会在talkcDlg.h中自动添加这三个事件处理函数的声明,在talkcDlg.cpp中生成消息映射的代码,和这三个函数的框架代码。6为为

32、CTalkcDlg对话框类添加其它的成员函数和成员变量对话框类添加其它的成员函数和成员变量成员变量:CMySocketm_sConnectSocket;/用来与服务器端连接的套接字。成员函数:voidOnClose();/用来处理与服务器端的通信。voidOnConnect();voidOnReceive();7手工添加的代码手工添加的代码在CTalkcDlg对话框类的talkcDlg.h中添加对于MySocket.h的包含命令,来获得对于套接字支持:#include“MySocket.h”在CTalkcDlg对话框类的talkcDlg.cpp中添加对于控件变量的初始化代码:/TODO:Add

33、extrainitializationhere/用户添加的控件变量的初始化代码BOOLCTalkcDlg:OnInitDialog()m_strServName=localhost;/服务器名=localhostm_nServPort=1000;/服务端口=1000UpdateData(FALSE);/更新用户界面/设置套接字类的对话框指针成员变量m_sConnectSocket.SetParent(this);8添加事件函数和成员函数的代码添加事件函数和成员函数的代码主要在CTalkcDlg对话框类的talkcDlg.cpp中和CMySocket类的Mysocket.cpp中,添加用户自己的

34、事件函数和成员函数的代码,要注意,这些函数的框架已经在前面的步骤中,由VC+的向导生成,只要将用户自己的代码填入其中即可。9进行测试。进行测试。测试应分步进行,在上面的步骤中,每作一步,都可以试着编译执行。图18Talkc客户端程序的类与消息驱动的关系 客户端程序的类与消息驱动客户端程序的类与消息驱动客户端程序的类与消息驱动客户端程序的类与消息驱动客户端程序的主要功能的代码和分析客户端程序的主要功能的代码和分析1应用程序类应用程序类CTalkcApp对应的文件对应的文件应用程序类CTalkcApp,对应的文件是talkc.h和talkc.cpp;talkc.h定义了CTalkcApp类,tal

35、kc.cpp是该类的实现代码,完全由VC+自动创建,用户不必作任何改动。2派生的套接字类派生的套接字类CMySocket对应的文件对应的文件CMySocket类 对 应 MySocket.h头 文 件 和MySocket.CPP文件,3对话框类对话框类CTalkcDlg对应的文件对应的文件对话框类CTalkcDlg,对应的文件是talkcDlg.h和talkcDlg.cpp。4其他文件其他文件对于VC+为talkc工程创建的其他文件,如stdafx.h和stdafx.cpp,以及Resource.h和talkc.rc都不需要作任何处理。创建服务器端程序创建服务器端程序同样利用可视化语言的集成开

36、发环境(IDE)来创建服务器端应用程序框架。步骤是:1使用使用MFC AppWizard创建服务器端应用程序框架。创建服务器端应用程序框架。2为对话框界面添加控件对象为对话框界面添加控件对象3为对话框中的控件对象定义相应的成员变量为对话框中的控件对象定义相应的成员变量4创建从创建从CAsyncSocket类继承的派生类类继承的派生类5为对话框类添加控件对象事件的响应函数为对话框类添加控件对象事件的响应函数6为为CTalksDlg对话框类添加其它的成员函数和成员变量对话框类添加其它的成员函数和成员变量7手工添加的代码手工添加的代码8添加事件函数和成员函数的代码添加事件函数和成员函数的代码9进行测

37、试。进行测试。图20Talks服务器端程序的类与消息驱动的关系 服务器端程序的流程和消息驱动服务器端程序的流程和消息驱动服务器端程序的流程和消息驱动服务器端程序的流程和消息驱动点对点交谈的服务器端程序的主要功能的代码和分析点对点交谈的服务器端程序的主要功能的代码和分析1CTalksApp类对应的文件类对应的文件talks.h和talks.cpp不需要做任何改动2CMySocket类对应的文件类对应的文件(1)MYSOCKET.H文件文件(2)MySocket.cpp文件文件3CTalksDlg类对应的文件类对应的文件(1)talksDlg.h(2)talksDlg.cpp文件文件4其它的文件不必改动其它的文件不必改动 推荐书目uuWindows网络编程 清华大学出版社uu网络编程人民邮电出版社谢谢大家!

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 生活常识

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁