第4章-MFC套接字编程_第1页
第4章-MFC套接字编程_第2页
第4章-MFC套接字编程_第3页
第4章-MFC套接字编程_第4页
第4章-MFC套接字编程_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

第4章MFC套接字编程杨明紫金学院计算机系数据结构2/3/2023内容MFC编程框架CAsyncSocket类编程CSocket类编程MFC编程MFC概述MFC类库是C++类库,构成了MFC编程框架。这些类分别封装了Win32应用程序编程接口、应用程序的概念、OLE特性、以及ODBC和DAO数据访问的功能。MFC类具有继承关系,有虚拟函数和动态约束,并提供了MFC的开发模板。MFC框架从总体上定义了应用程序的轮廓,并提供了用户接口的标准实现方法,程序员只须通过预定义的接口把具体应用程序特有的东西填入这个轮廓,就能建立Windows下的应用程序。典型的MFC应用程序的构成MFC对象间的交互作用关系MFC消息处理消息映射就是让程序员指定用来处理某个消息的某个MFC类使用MFC提供的ClassWizard类向导,可以在处理消息的类中添加处理消息的成员函数,方便地实现消息映射。在此基础上,程序员可将自己的代码添加到这些消息处理函数中,实现所希望的消息处理。如果派生类要覆盖基类的消息处理函数,就用ClassWizard在派生类中添加一个消息映射条目,用同样的原型定义一个函数,然后实现该函数。MFC的消息与映射处理Windows消息以前缀“WM_”打头的消息,Windows消息直接被送给MFC的窗口过程处理,窗口过程再调用对应的消息处理函数。控制通知消息,是控制子窗口送给父窗口的通知消息。窗口过程调用对应的消息处理函数。命令消息,这是来自菜单、工具条按钮、加速键等用户接口对象的WM_COMMAND通知消息,属于应用程序自己定义的消息。MFC消息映射的实现方法程序员可以使用MFC的类向导ClassWizard来实现消息映射。类向导在源码中添加一些消息映射的内容,并声明和实现消息处理函数。MFC类的构成8基于CCmdTarget和CWnd派生的MFC类9MFC编程框架10MFCWinSock类的编程MFCWinSock类为简化套接字网络编程,更方便地利用Windows的消息驱动机制,微软的基础类库MFC,提供了两个套接字类,在不同的层次上对WindowsSocketAPI函数进行了封装,提供了两种编程模式。CAsyncSocket类和CSocket类CAsyncSocket类特点在很低的层次上对WindowsSocketsAPI进行了封装它的成员函数和WindowsSocketsAPI的函数调用直接对应。一个CAsyncSocket对象代表了一个Windows套接字。它是网络通信的端点。除了把套接字封装成C++的面向对象的形式供程序员使用以外,这个类唯一所增加的抽象就是将那些与套接字相关的Windows消息变为CAsyncSocket类的回调函数。CSocket类特点从CAsyncSocket类派生,是对WindowsSocketsAPI的高级封装。CSocket类继承了CAsyncSocket类的许多成员函数,用法一致。CSocket类的高级表现在三个方面:(1)CSocket结合archive类来使用套接字。(2)CSocket管理了通信的许多方面,如字节顺序问题和字符串转换问题。(3)CSocket类为Windows消息的后台处理提供了阻塞的工作模式。CAsyncSocket类的定义14CAsyncSocket类的定义15六种套接字相关的事件与通知消息当事件发生时,套接字对象会收到相应的通知消息,并自动执行套接字对象响应的事件处理函数。FD_READ事件通知:通知有数据可读。FD_WRITE事件通知:通知可以写数据。FD_ACCEPT事件通知:通知监听套接字有连接请求可以接受。FD_CONNECT事件通知:通知请求连接的套接字,连接的要求已被处理。FD_CLOSE事件通知:通知套接字已关闭。FD_OOB事件通知:通知将有带外数据到达。CAsyncSocket类的定义17套接字类的通知函数CAsyncSocket类这六个网络事件对应的事件处理函数virtualvoidOnReceive(intnErrorCode);对应FD_READ事件virtualvoidOnSend(intnErrorCode);对应FD_WRITE事件virtualvoidOnAccept(intnErrorCode);对应FD_ACCEPT事件virtualvoidOnConnect(intnErrorCode);对应FD_CONNECT事件virtualvoidOnClose(intnErrorCode);对应FD_CLOSE事件virtualvoidOnOutOfBandData(intnErrorCode);对应FD_OOB事件重载套接字对象的回调函数 MFC框架自动调用通知函数,使得你可以在套接字被通知的时候来优化套接字的行为。创建CasyncSocket类对象定义异步套接字对象变量如:CAsyncSocketaa; aa.Create(。。。。。。);如:CAsyncSocket*Pa; Pa->Create(。。。。。。);

创建CasyncSocket类对象创建异步套接字对象的底层套接字句柄格式:BOOLCreate(UINTnSocketPort=0, IntnSocketType=SOCK_STREAM, LongIevent=FD_READ|FD_WRITE|FD_OOB| FD_ACCEPT|FD_CONNECT|FD_CLOSE, LPCTSTRlpszSocketAddress=NULL);例:CAsyncSocket*pSocket=newCAsyncSocket;intnPort=27;pSocket->Create(nPort,SOCK_STREAM);客户端套接字对象请求连接客户端套接字对象请求连接到服务器端套接字对象在服务器端套接字对象已经进入监听状态之后,客户应用程序可以调用CAsyncSocket类的Connect()成员函数,向服务器发出一个连接请求,格式一:BOOLConnect(LPCTSTRlpszHostAddress,UINTnHostPort);格式二:BOOLConnect(constSOCKADDR*lpSockAddr,intnSockAddrLen);当调用结束返回时,都会发生FD_CONNECT事件接受连接请求服务器接受客户机的连接请求服务器应用程序必须首先创建一个监听套接字对象,专门用来监听来自客户机的连接请求。调用监听套接字对象的Listen成员函数,BOOLListen(intnConnectionBacklog=5);当Listen函数确认并接纳了一个来自客户端的连接请求后,会触发FD_ACCEPT事件创建一个新的连接套接字,这个套接字专门用来与客户端连接,并进行数据的传输。调用监听套接字对象的Accept成员函数,调用格式为:virtualBOOLAccept(CAsyncSocket&rConnectedSocket,SOCKADDR*lpSockAddr=NULL,int*lpSockAddrLen=NULL);发送与接收流式数据用Send成员函数发送数据格式:virtualintSend(constvoid*lpBuf,intnBufLen,intnFlags=0);对于一个CAsyncSocket套接字对象,当它的发送缓冲区腾空时,会激发FD_WRITE事件。用Receive成员函数接收数据格式:VirtualintReceive(Void*lpBuf,IntnBufLen,IntnFlags=0);对于一个CAsyncSocket套接字对象,当有数据到达它的接收队列时,会激发FD_READ事件,套接字会得到已经有数据到达的通知,MFC框架会自动调用这个套接字对象的OnReceive事件处理函数。在应用程序将数据取走之前,套接字接收的数据将一直保留在套接字的缓冲区中。CAsyncSocket类编程步骤24步骤服务器客户机1//创建服务器侦听套接字对象CAsyncSocketsockListen;//创建客户机套接字对象CAsyncSocketsockClient;2//创建SOCKET句柄,绑定到指定端口sockListen.Create(nPort);//创建SOCKET句柄,自动选择本地可用端口sockClient.Create();3//启动监听,时刻准备接受客户连接请求sockListen.Listen();

4

//请求连接到服务器sockClient.Connect(strAddr,nPort);5//创建一个新的服务器套接字对象CAsyncSocketsockServer;//接受新连接sockListen.Accept(sockServer);

6//接收数据sockServer.Receive(pBuf,nLen);或//发送数据sockServer.Send(pBuf,nLen);或两者//发送数据sockClient.Send(pBuf,nLen);或/接收数据sockClient.Receive(pBuf,nLen);或两者7//禁用服务器套接字某些操作sockServer.ShutDown();//禁用客户机套接字某些操作sockClient.ShutDown();8//关闭服务器套接字sockServer.Close();//关闭客户机套接字sockClient.Close();9//关闭服务器侦听套接字sockListen.Close();

CAsyncSocket类的应用实例实现目标应用实例是一个简单的聊天室程序,采用客户/服务器模式,分为客户端程序和服务器端程序。由于服务器只能支持一个客户,实际是一个点对点通信的程序。客户端程序和服务器程序通过网络交换聊天的字符串内容,并在窗口的列表框中显示。创建客户端应用程序使用MFCAppWizard创建客户端应用程序框架使用MFCAppWizard设置创建的骨架工程的有关信息为对话框界面添加控件对象设计对话框通过resourceView设计并构建对话框修改对话框中的控件属性对话框设置控件类型控件IDCaption静态文本statictextIDC_STATIC_SERVNAME服务器名称静态文本statictextIDC_STATIC_SERVPORT服务器端口静态文本statictextIDC_STATIC_MSG消

息静态文本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_RECEIVED

为对话框中的控件对象定义相应的成员变量对话框中的控件对象对应的成员变量

控件IDControlIDs变量名称MemberVariableName变量类别Category变量类型VariableTypeIDC_BUTTON_CONNECTm_btnConnectControlCButtonIDC_EDIT_SERVNAMEm_strServNameValueCStringIDC_EDIT_SERVPORTm_strServPortValueintIDC_EDIT_MSGm_strMsgValueCStringIDC_LIST_SENTm_listSentControlCListBoxIDC_LIST_RECEIVEDm_listRecetvedControlCListBox

创建从CAsyncSocket类继承的派生类为了能够捕获并响应socket事件,应创建用户自己的套接字类。从CAsyncSocket类派生,将套接字事件传递给对话框,以便执行用户自己的事件处理函数。为套接字类添加响应消息的事件处理成员函数为套接字类添加一般的成员函数和成员变量对这个套接字类,添加一个私有的成员变量,是一个对话框类的指针。private:CTalkcDlg*m_pDlg;为套接字类添加一般的成员变量为套接字类添加成员函数再添加一个成员函数:voidSetParent(CTalkcDlg*pDlg);客户端程序的类与消息驱动客户端程序主要代码说明1.应用程序类CTalkcApp对应的文件应用程序类CTalkcApp,对应的文件是talkc.h和talkc.cpp;talkc.h定义了CTalkcApp类,talkc.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都不需要作任何处理。创建服务器端程序1.使用MFCAppWizard创建服务器端应用程序框架2.为对话框界面添加控件对象3.为对话框中的控件对象定义相应的成员变量4.创建从CAsyncSocket类继承的派生类5.为对话框类添加控件对象事件的响应函数6.为CTalksDlg对话框类添加其它成员函数和成员变量7.手工添加的代码8.添加事件函数和成员函数的代码9.进行测试。

服务器端程序的流程和消息驱动创建服务器1.使用MFC应用程序向导创建服务器程序框架43创建服务器2.为服务器对话框添加控件,构建程序主界面44创建服务器3.为对话框中的控件对象定义相应的成员变量4.创建从CAsyncSocket类派生的子类CServerSocket,处理与客户机的通信5.为对话框类CServerDlg中的三个按钮控件添加单击事件处理函数6.为CServerDlg类添加与套接字关联的成员变量和成员函数7.手工添加部分代码8.添加事件函数和成员函数业务逻辑代码45服务器代码分析同客户机一样,应用程序Server.h和Server.cpp对应CServerApp类的定义和实现,完全由VC++2010的MFC向导自动创建,是整个项目的入口文件,编程者不需做任何改动。Resource.h、stdafx.h、stdafx.cpp、targetver.h等由系统自动生成,不需改动。教材重点给出ServerSocket.h、ServerSocket.cpp、ServerDlg.h和ServerDlg.cpp这四个文件的编码清单。46服务器代码分析服务器运行初始界面47客户机服务器联合测试客户机与服务器交流界面截图48CSOCKET类编程模型CSocket类的高级特性CSocket结合archive类来使用套接字。CSocket管理了通信的许多方面,如字节顺序问题和字符串转换问题。CSocket类为Windows消息的后台处理提供了阻塞的工作模式CSOCKET类编程模型CArchive、CSocketFile和CSocket协同工作模型50创建CSocket对象创建步骤(1)调用CSocket类的构造函数,创建一个空的CSocket对象。(2)调用此CSocket对象的Create()成员函数,创建对象的底层套接字。调用格式是:BOOLCreate(UINTnSocketPort=端口号,

IntnSocketPort=SOCK_STREAM|SOCK_DGRAM, LPCTSTRlpszSocketAddress=套接字所用网络地址);如果打算使用CArchive对象和套接字一起进行数据传输工作,必须使用流式套接字。建立连接相同的方法CSocket类使用基类CAsyncSocket的同名成员函数Connect()、Listen()、Accept()来建立服务器和客户机套接字之间的连接,使用方法相同。不同的是CSocket类的Connect()和Accept()支持阻塞调用。比如:在调用Connect()函数时会发生阻塞,直到成功地建立了连接或有错误发生才返回,在多线程的应用程序中,一个线程发生阻塞,其他的线程仍能处理Windows事件。CSocket对象从不调用OnConnect()事件处理函数发送和接收数据对于数据报套接字直接使用CSocket类的SendTo()、ReceiveFrom()成员函数来发送和接收数据。对于流式套接字首先在服务器和客户机之间建立连接,然后使用CSocket类的Send()、Receive()成员函数来发送和接收数据,它们的调用方式与CAsyncSocket类相同。

不同的是CSocket类的这些函数工作在阻塞的模式。比如,一旦调用了Send()函数,在所有的数据发送之前,程序或线程将处于阻塞的状态。一般将CSocket类与CArchive类和CSocketFile类结合,来发送和接收数据,这将使编程更为简单。CSocket对象从不调用OnSend()事件处理函数。CSocket类的使用CSocket类与CArchive类和CSocketFile类使用CSocket类的最大优点在于,应用程序可以在连接的两端通过CArchive对象来进行数据传输。具体做法创建CSocket类对象创建一个基于CSocketFile类的文件对象,并把它的指针传给上面的已创建的CSocket对象。分别创建用于输入和输出的CArchive对象,并将它们与这个CSocketFile文件对象连接。利用CArchive对象来发送和接收数据。CSOCKET类编程模型55步骤服务器客户端1//创建服务器侦听套接字对象CSocketsockListen;//创建客户机套接字对象CSocketsockClient;2//创建SOCKET句柄,绑定指定端口sockListen.Create(nPort);//创建SOCKET句柄,自动选择本地可用端口sockClient.Create();3//启动服务器端侦听,时刻准备接受连接sockListen.Listen();

4

//向服务器发起连接请求sockClient.Connect(strAddr,nPort);5//创建一个新的服务器套接字对象CSocketsockServer;//接受客户机连接sockListen.Accept(sockServer);

6//创建一个与套接字关联的文件对象CSocketFilefile(&sockServer);//创建一个与套接字关联的文件对象CSocketFilefile(&sockClient);7//在服务器创建与套接字文件对象关联的归档对象,用于输入或输出CArchivearIn(&file,CArchive::load);-或-CArchivearOut(&file,CArchive::store);-或两者-//在客户机创建与套接字文件对象关联的归档对象,用于输入或输出CArchivearIn(&file,CArchive::load);-或-CArchivearOut(&file,CArchive::store);-或两者-8//使用归档对象传输数据arIn>>dwValu

温馨提示

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

评论

0/150

提交评论