资源预览内容
第1页 / 共68页
第2页 / 共68页
第3页 / 共68页
第4页 / 共68页
第5页 / 共68页
第6页 / 共68页
第7页 / 共68页
第8页 / 共68页
第9页 / 共68页
第10页 / 共68页
亲,该文档总共68页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第5章 MFC WinSockMFC WinSock类的编程类的编程第五章第五章 MFC WinSockMFC WinSock类的编程类的编程第5章 MFC WinSockMFC WinSock类的编程类的编程第五章第五章 MFC WinSockMFC WinSock类的编程类的编程 为简化套接字网络编程,更方便地利为简化套接字网络编程,更方便地利用用Windows Windows 的消息驱动机制,微软的的消息驱动机制,微软的 MFCMFC提供了两个套接字类,在不同的层次上对提供了两个套接字类,在不同的层次上对Win Socket APIWin Socket API函数进行了封装,为编写函数进行了封装,为编写网络通信程序,提供了两种编程模式。网络通信程序,提供了两种编程模式。第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类类异步套节字类异步套节字类在低层次上对在低层次上对Win Sockets APIWin Sockets API进行了封装。进行了封装。特点:特点:u它的成员函数和它的成员函数和Windows Sockets APIWindows Sockets API的函的函数调用直接对应。数调用直接对应。u一个一个CAsyncSocketCAsyncSocket对象代表了一个对象代表了一个WindowsWindows套接字,它是网络通信的端点;套接字,它是网络通信的端点;u将那些与套接字相关的将那些与套接字相关的WindowsWindows消息变为该消息变为该类的回调函数。类的回调函数。第5章 MFC WinSockMFC WinSock类的编程类的编程CSocketCSocket类类 从从CAsyncSocketCAsyncSocket类派生,是对类派生,是对Win Sockets APIWin Sockets API的高级封装。继承了的高级封装。继承了CAsyncSocketCAsyncSocket类的许多成员函数。类的许多成员函数。CSocketCSocket类的高级表现在三个方面:类的高级表现在三个方面:uCSocketCSocket结合结合archivearchive类来使用套接字。类来使用套接字。uCSocketCSocket管理了通信的许多方面,如管理了通信的许多方面,如字字节顺序问题和字符串转换问题节顺序问题和字符串转换问题。uCSocketCSocket类为类为WindowsWindows消息的消息的后台处理提后台处理提供了阻塞供了阻塞的工作模式。的工作模式。 第5章 MFC WinSockMFC WinSock类的编程类的编程CSocketCSocket类类 在在MFCMFC中,有一个名为中,有一个名为afxSock.hafxSock.h的包含的包含文件,在这个文件中定义了文件,在这个文件中定义了CAsyncSocketCAsyncSocket,CSocketCSocket,和,和CSocketFileCSocketFile这三个套接字类。这三个套接字类。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1 CasyncSocketCasyncSocket类类CAsyncSocketCAsyncSocket类从类从CobjectCobject类派生而来类派生而来:图图5.1 CAsyncSocket类的派生关系类的派生关系 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.1 使用使用CAsyncSocketCAsyncSocket类的一般步骤类的一般步骤ServerServer端端ClientClient端端构造套节字,构造套节字,CASyncSocketCASyncSocket SockServerSockServer同前同前 SockClientSockClient创建创建SocketSocket句柄,绑定到指定端口句柄,绑定到指定端口SockServer.SockServer.CreateCreate(nPort(nPort,),)同前同前监听,准备接受连接请求监听,准备接受连接请求SockServer.ListenSockServer.Listen()()连接到服务器连接到服务器SockClientSockClient.connection(IP,nPort.connection(IP,nPort) )构造新套接字,构造新套接字, CASyncSocketCASyncSocket SockRecvSockRecv接受连接接受连接 SockRecv.Accept(SockRecvSockRecv.Accept(SockRecv) )接收数据接收数据SockRecv.Receive(pBuf,nLenSockRecv.Receive(pBuf,nLen) )发送数据发送数据SockClient.Send(pBuf,nLenSockClient.Send(pBuf,nLen) )关闭套接字连接关闭套接字连接SockRecv.CloseSockRecv.Close( )( )关闭套接字连接关闭套接字连接SockRecv.CloseSockRecv.Close( ( ) )第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.1 使用使用CAsyncSocketCAsyncSocket类的一般步骤类的一般步骤注意几个问题:注意几个问题:u阻塞处理:不支持阻塞处理:不支持u字节顺序的转换字节顺序的转换第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.2 创建创建CasyncSocketCasyncSocket类对象类对象 CAsyncSocketCAsyncSocket类对象称为异步套接字对象。类对象称为异步套接字对象。创建异步套接字对象分为两个步骤:创建异步套接字对象分为两个步骤:u构造一个构造一个CAsyncSocketCAsyncSocket对象对象: :CAsyncSocketCAsyncSocket aaaa;u创建该对象的底层的创建该对象的底层的SOCKETSOCKET句柄句柄: :aa.Createaa.Create()()第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.2 创建创建CasyncSocketCasyncSocket类对象类对象CreateCreate函数创建底层套接字句柄函数创建底层套接字句柄 通过调用通过调用CAsyncSocketCAsyncSocket类的类的Create()Create()成员函数,成员函数,创建该对象的底层套接字句柄,决定套接字对象的具创建该对象的底层套接字句柄,决定套接字对象的具体特性。调用格式为:体特性。调用格式为: BOOL Create( UINT nSocketPort=0,Int nSocketType = SOCK_STREAM,Long Ievent = FD_READ |FD_WRITE |FD_OOB | FD_ACCEPT |FD_CONNECT |FD_CLOSE, LPCTSTR lpszSocketAddress = NULL ); 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.2 创建创建CasyncSocketCasyncSocket类对象类对象举例:举例: 创建一个使用创建一个使用2727端口的流式异步套接字端口的流式异步套接字对象。对象。 CAsyncSocket* pSocket = new CAsyncSocket; int nPort = 27; pSocket-Create( nPort, SOCK_STREAM ); 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件1 1六种套接字相关的事件与通知消息六种套接字相关的事件与通知消息 CreateCreate函数的参数函数的参数IeventIevent为可以选用的符号常为可以选用的符号常量,是在量,是在winsock.hwinsock.h文件中定义的:文件中定义的:#define #define FD_READFD_READ 0x01 0x01 可以可以RecvRecv#define #define FD_WRITEFD_WRITE0x020x02 可以可以SendSend#define #define FD_OOBFD_OOB 0x040x04 有带外数据到达有带外数据到达#define #define FD_ACCEPTFD_ACCEPT0x080x08 有连接请求有连接请求#define #define FD_CONNECTFD_CONNECT 0x100x10 连接请求已处理连接请求已处理#define #define FD_CLOSEFD_CLOSE0x200x20 套接字已关闭套接字已关闭第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件 他们代表他们代表MFC MFC 套接字对象可以接受并处理的六种套接字对象可以接受并处理的六种网络事件,当事件发生时,套接字对象会收到相应的网络事件,当事件发生时,套接字对象会收到相应的通知消息,并自动执行套接字对象响应的事件处理函通知消息,并自动执行套接字对象响应的事件处理函数。数。uFD_READFD_READ事件:通知有数据可读。事件:通知有数据可读。uFD_WRITEFD_WRITE事件:通知可以写数据。事件:通知可以写数据。uFD_ACCEPTFD_ACCEPT事件:通知监听套接字有连接请求可以接事件:通知监听套接字有连接请求可以接受。受。uFD_CONNECTFD_CONNECT事件:通知请求连接的套接字,连接的要事件:通知请求连接的套接字,连接的要求已被处理。求已被处理。uFD_CLOSEFD_CLOSE事件:通知套接字已关闭。事件:通知套接字已关闭。uFD_OOBFD_OOB事件:通知将有带外数据到达。事件:通知将有带外数据到达。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件2 2MFCMFC框架对于六个网络事件的处理框架对于六个网络事件的处理 按照按照WindowsWindows的消息驱动机制,的消息驱动机制,MFCMFC框架应框架应当把消息发送给相应的套接字对象,并调用作当把消息发送给相应的套接字对象,并调用作为该对象成员函数的事件处理函数。事件与处为该对象成员函数的事件处理函数。事件与处理函数是一一映射的。理函数是一一映射的。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件 在在afxSock.hafxSock.h文件的文件的CAsyncSocketCAsyncSocket类的声明中,定类的声明中,定义了与这六个网络事件对应的事件处理函数:义了与这六个网络事件对应的事件处理函数:uvirtual void virtual void OnReceiveOnReceive(int(int nErrorCodenErrorCode); ); 对应对应 FD_READFD_READ事件事件uvirtual void virtual void OnSendOnSend(int(int nErrorCodenErrorCode); ); 对应对应 FD_WRITEFD_WRITE事件事件uvirtual void virtual void OnAcceptOnAccept(int(int nErrorCodenErrorCode); ); 对应对应 FD_ACCEPTFD_ACCEPT事件事件uvirtual void virtual void OnConnectOnConnect(int(int nErrorCodenErrorCode); ); 对应对应 FD_CONNECTFD_CONNECT事件事件第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件uvirtual void virtual void OnCloseOnClose(int(int nErrorCodenErrorCode); ); 对应对应 FD_CLOSE FD_CLOSE 事件事件uvirtual void virtual void OnOutOfBandDataOnOutOfBandData(int(int nErrorCodenErrorCode); ); 对应对应 FD_OOB FD_OOB 事件事件 当某个网络事件发生时,当某个网络事件发生时,MFC MFC 自动调用套接字自动调用套接字对象对应的事件处理函数。这相当于给了套接字对对象对应的事件处理函数。这相当于给了套接字对象一个通知,告诉它某个重要的事件已经发生。所象一个通知,告诉它某个重要的事件已经发生。所以也称之为套接字类的通知函数或回调函数。以也称之为套接字类的通知函数或回调函数。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.3 CAsyncSocket类的消息事件类的消息事件3 3重载套接字对象的回调函数重载套接字对象的回调函数 如果从如果从CAsyncSocketCAsyncSocket 类上派生了自己的套接字类上派生了自己的套接字类,类, 你必须重载应用程序所感兴趣的那些网络事件你必须重载应用程序所感兴趣的那些网络事件所对应的通知函数。所对应的通知函数。 MFCMFC框架自动调用通知函数,这样可以在套接字框架自动调用通知函数,这样可以在套接字被通知的时候来优化套接字的行为。被通知的时候来优化套接字的行为。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.4 客户端请求连接到服务器端客户端请求连接到服务器端 服务器端套接字对象已经进入监听状态后,客服务器端套接字对象已经进入监听状态后,客户应用程序可以调用户应用程序可以调用CAsyncSocketCAsyncSocket类的类的Connect()Connect()成成员函数,向服务器发出一个连接请求:员函数,向服务器发出一个连接请求:格式一:格式一: BOOL BOOL ConnectConnect( LPCTSTR ( LPCTSTR lpszHostAddresslpszHostAddress, , UINT UINT nHostPortnHostPort ); );格式二:格式二: BOOL BOOL ConnectConnect( const SOCKADDR* ( const SOCKADDR* lpSockAddrlpSockAddr, , intint nSockAddrLennSockAddrLen ) );第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.4 客户端请求连接到服务器端客户端请求连接到服务器端 如果调用成功或者发生了错误,当如果调用成功或者发生了错误,当调用结调用结束返回束返回时,都会发生时,都会发生FD_CONNECTFD_CONNECT事件,事件,MFCMFC框架框架会自动调用客户端套接字的会自动调用客户端套接字的OnConnectOnConnect()()事件处事件处理函数,并将错误代码作为参数传送给它。它理函数,并将错误代码作为参数传送给它。它的原型调用格式如下,的原型调用格式如下, void void OnConnectOnConnect( ( intint nErrorCodenErrorCode ); ); nErrorCodenErrorCode=0=0时时 连接成功连接成功第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.5 服务器接受客户机的连接请求服务器接受客户机的连接请求 服务器端使用服务器端使用CAsyncSocketCAsyncSocket流式套接字对象,流式套接字对象,按以下步骤来接收客户端的连接请求:按以下步骤来接收客户端的连接请求:1 1)服务器程序必须首先创建一个服务器程序必须首先创建一个CAsyncSocketCAsyncSocket流式套接字对象,并调用它的流式套接字对象,并调用它的Create Create 成员函成员函数创建底层套接字句柄(监听专用)。数创建底层套接字句柄(监听专用)。2 2)调用监听套接字对象的调用监听套接字对象的ListenListen成员函数。调成员函数。调用格式是:用格式是:B BOOL Listen( OOL Listen( intint nConnectionBacklognConnectionBacklog=5)=5);第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.5 服务器接受客户机的连接请求服务器接受客户机的连接请求 当当Listen Listen 函数确认并接纳了一个来自客户端的函数确认并接纳了一个来自客户端的连接请求后,会触发连接请求后,会触发FD_ACCEPTFD_ACCEPT事件,监听套接字会事件,监听套接字会收到通知,表示监听套接子已经接纳了一个客户的收到通知,表示监听套接子已经接纳了一个客户的连接请求,连接请求,MFCMFC框架会自动调用框架会自动调用OnAcceptOnAccept事件处理函事件处理函数,原型如下:数,原型如下:void void OnAcceptOnAccept( ( intint nErrorCodenErrorCode ); ); 应重载此函数,在其中调用监听套接字对象的应重载此函数,在其中调用监听套接字对象的AcceptAccept函数,来接收客户端的连接请求。函数,来接收客户端的连接请求。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.5 服务器接受客户机的连接请求服务器接受客户机的连接请求3 3)创建一个新的空的套接字对象。这个套接字创建一个新的空的套接字对象。这个套接字专门用来与客户端连接,并进行数据的传输。专门用来与客户端连接,并进行数据的传输。称为连接套接字。称为连接套接字。4 4)调用监听套接字对象的调用监听套接字对象的AcceptAccept成员函数,调成员函数,调用格式为:用格式为:virtual BOOL Accept( CAsyncSocket & rConnectedSocket,SOCKADDR * lpSockAddr = NULL,int * lpSockAddrLen = NULL );第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.6 发送与接收流式数据发送与接收流式数据对于流式套接字对象:对于流式套接字对象:u则使用则使用CAsyncSocketCAsyncSocket类的类的Send Send 成员函成员函数向流式套接字发送数据数向流式套接字发送数据u使用使用ReceiveReceive成员函数从流式套接字接成员函数从流式套接字接收数据。收数据。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.6 发送与接收流式数据发送与接收流式数据1 1用用SendSend成员函数发送数据成员函数发送数据格式:格式:virtual int Send( const void* lpBuf, int nBufLen, int nFlags = 0); 对于一个对于一个CAsyncSocketCAsyncSocket套接字对象,当它的套接字对象,当它的发发送缓冲区腾空送缓冲区腾空时,会激发时,会激发FD_WRITEFD_WRITE事件,套接字会事件,套接字会得到通知,得到通知,MFC MFC 框架会自动调用这个套接字对象的框架会自动调用这个套接字对象的OnSendOnSend 事件处理函数。事件处理函数。 应重载这个函数,在其中应重载这个函数,在其中调用调用SendSend成员函数来发送数据。成员函数来发送数据。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.6 发送与接收流式数据发送与接收流式数据2 2用用ReceiveReceive成员函数接收数据成员函数接收数据格式:格式:intint ReceiveReceive( Void* ( Void* lpBuflpBuf, , IntInt nBufLennBufLen, , IntInt nFlagsnFlags = 0); = 0); 对于一个对于一个CAsyncSocketCAsyncSocket 套接字对象,当有套接字对象,当有数据到数据到达它的接收队列时达它的接收队列时,会激发,会激发FD_READFD_READ事件,套接字会事件,套接字会得到已经有数据到达的通知,得到已经有数据到达的通知,MFCMFC框架会自动调用这框架会自动调用这个套接字对象的个套接字对象的 OnReceiveOnReceive事事 件处理函数。应重载件处理函数。应重载这个函数,调用这个函数,调用ReceiveReceive成员函数来接收数据。成员函数来接收数据。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.7 关闭套接字关闭套接字1 1使用使用CAsyncSocketCAsyncSocket类的类的CloseClose成员函数成员函数格式:格式:void void CloseClose( );( );2 2使用使用CAsyncSocketCAsyncSocket类的类的ShutDownShutDown()()成员函成员函数数 使用使用ShutDownShutDown()()成员函数,可以选择关闭套接成员函数,可以选择关闭套接字的方式。将套接字的方式。将套接字置为不能发送数据,或不能接字置为不能发送数据,或不能接收数据,或二者均不能的状态。收数据,或二者均不能的状态。格式:格式:BOOL BOOL ShutDownShutDown(int(int nHownHow=sends);=sends);receivesreceives、bothboth 第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.8 错误处理错误处理 调用调用CAsyncSocketCAsyncSocket对象的成员函数后,返对象的成员函数后,返回一个逻辑型的值:回一个逻辑型的值:u执行成功,返回执行成功,返回TRUETRUE;u失败,返回失败,返回FALSEFALSE。 调用调用CAsyncSocketCAsyncSocket对象的对象的GetLastErrorGetLastError()()成员函数,来获取更详细的错误代码,并进行成员函数,来获取更详细的错误代码,并进行相应的处理。相应的处理。格式:格式:intint GetLastErrorGetLastError( );( );第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.9 其它的成员函数其它的成员函数1 1关于套接字属性的函数关于套接字属性的函数uSetSocketOptSetSocketOpt:设置底层套接字的属性;:设置底层套接字的属性;uGetSocketOptGetSocketOpt:获取套接字的设置信息;:获取套接字的设置信息;uIOCtlIOCtl:控制套接字的工作模式;:控制套接字的工作模式;第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.9 其它的成员函数其它的成员函数2 2发送和接收数据发送和接收数据 如果创建的是如果创建的是数据报类型数据报类型的套接字:的套接字:u用用SendToSendTo()()成员函数来向指定的地址发成员函数来向指定的地址发送数据,事先不需要建立发送端和接收送数据,事先不需要建立发送端和接收端之间的连接端之间的连接u用用ReceiveFromReceiveFrom()()成员函数可以从某个成员函数可以从某个指定的网络地址接收数据。指定的网络地址接收数据。第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.9 其它的成员函数其它的成员函数SendToSendTo有两种重载的形式:有两种重载的形式:int SendTo( const void* lpBuf, int nBufLen, UINT nHostPort,LPCTSTR lpszHostAddress = NULL,int nFlags = 0 );int SendTo( const void* lpBuf, int nBufLen, const SOCKADDR*lpSockAddr, int nSockAddrLen, int nFlags= 0);第5章 MFC WinSockMFC WinSock类的编程类的编程5.1.9 其它的成员函数其它的成员函数ReceiveFromReceiveFrom也有两种重载的形式也有两种重载的形式: :int ReceiveFrom( void* lpBuf, int nBufLen, CString& rSocketAddress,UINT& rSocketPort, int nFlags = 0 );int ReceiveFrom( void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0 ); 第5章 MFC WinSockMFC WinSock类的编程类的编程5.2 CSocket类类 CSocketCSocket类是从类是从CAsyncSocketCAsyncSocket类派生而来类派生而来的,它们的派生关系如图的,它们的派生关系如图5.25.2:图图5.2 5.2 CSocketCSocket类的派生关系类的派生关系 第5章 MFC WinSockMFC WinSock类的编程类的编程5.2 CSocket类类 从从CAsyncSocketCAsyncSocket类派生,是对类派生,是对Win Sockets APIWin Sockets API的高级封装。继承了的高级封装。继承了CAsyncSocketCAsyncSocket类的许多成员函数。类的许多成员函数。CSocketCSocket类的高级表现在三个方面:类的高级表现在三个方面:uCSocketCSocket结合结合archivearchive类来使用套接字。类来使用套接字。uCSocketCSocket管理了通信的许多方面,如管理了通信的许多方面,如字字节顺序问题和字符串转换问题节顺序问题和字符串转换问题。uCSocketCSocket类为类为WindowsWindows消息的消息的后台处理提后台处理提供了阻塞供了阻塞的工作模式。的工作模式。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.1 创建创建CSocketCSocket对象对象分为两个步骤:分为两个步骤:u调用调用CSocketCSocket类的构造函数,创建一个空的类的构造函数,创建一个空的CSocketCSocket对象。对象。u调用此调用此CSocketCSocket对象的对象的Create()Create()成员函数,创成员函数,创建对象的底层套接字。调用格式是:建对象的底层套接字。调用格式是:BOOL Create( UINT BOOL Create( UINT nSocketPortnSocketPort = = 端口号,端口号, IntInt n nSocketPortSocketPort=SOCK_STREAM|SOCK_DGRAM=SOCK_STREAM|SOCK_DGRAM, LPCTSTR LPCTSTR lpszSocketAddresslpszSocketAddress= =套接字用的套接字用的IP)IP); 如果用如果用CArchiveCArchive对象和套接字一起进行数据传输对象和套接字一起进行数据传输工作,必须使用流式套接字工作,必须使用流式套接字。第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.2 建立连接建立连接 CSocketCSocket类类Connect()Connect()、Listen()Listen()、Accept()Accept()来建来建立服务器和客户机套接字之间的连接,与基类的使用立服务器和客户机套接字之间的连接,与基类的使用方法相同。方法相同。不同点:不同点:uCSocketCSocket的的ConnectConnect()()和和AcceptAccept()()支持支持阻塞调用阻塞调用。调用调用Connect()Connect()函数时会发生阻塞,直到成功函数时会发生阻塞,直到成功地建立了连接或有错误发生才返回。地建立了连接或有错误发生才返回。uCSocketCSocket对象对象不调用不调用OnConnectOnConnect()()事件处理函数。事件处理函数。第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.3 发送和接收数据发送和接收数据u数据报套接字:数据报套接字:使用使用SendToSendTo()()、ReceiveFromReceiveFrom() () 成员函数来发送和接收数据。成员函数来发送和接收数据。 u对于流式套接字:对于流式套接字:使用使用Send()Send()、Receive()Receive()函数函数来发送和接收数据,来发送和接收数据,调用方式与调用方式与CAsyncSocketCAsyncSocket类相同,类相同,不同在于:不同在于:uCSocketCSocket类的这些函数工作在阻塞的模式。可以类的这些函数工作在阻塞的模式。可以将将CSocketCSocket类与类与CArchiveCArchive类和类和CSocketFileCSocketFile类结类结合,来发送和接收数据。合,来发送和接收数据。uCSocketCSocket对象对象从不调用从不调用OnSendOnSend()()事件处理函数。事件处理函数。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.3 发送和接收数据发送和接收数据 CSocketCSocket对象在调用对象在调用ConnectConnect、SendSend、AcceptAccept、CloseClose、ReceiveReceive等成员函数后,这些函数在完成任等成员函数后,这些函数在完成任务之后才会返回。因此,务之后才会返回。因此,ConnectConnect和和SendSend不会导致不会导致OnConnectOnConnect和和OnSendOnSend被调用。被调用。第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.4 CArchive类和类和CSocketFile类类 使用使用CSocketCSocket的的最大优点最大优点在于,程序可在连接的在于,程序可在连接的两端两端通过通过CArchiveCArchive对象来进行数据传输对象来进行数据传输。方法是:。方法是:u创建创建CSocketCSocket类对象类对象u创建一个基于创建一个基于CSocketFileCSocketFile类的文件对象,类的文件对象,并把它的指针传给已创建的并把它的指针传给已创建的CSocketCSocket对象,对象,u分别创建分别创建用于输入和输出的用于输入和输出的CArchiveCArchive对象,对象,并将它们与并将它们与CSocketFileCSocketFile文件对象连接,文件对象连接,u利用利用CArchiveCArchive对象来发送和接收数据。对象来发送和接收数据。第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.4 CArchive类和类和CSocketFile类类示例代码:示例代码: CSocket exSocket; CSocketFile* pExFile; CArchive* pCArchiveIn; CArchive* pCArchiveOut; exSocket.Create(); pExFile = new CSocketFile ( & exSocket,TRUE); pCArchiveIn = new CArchive ( pExFile, CArchive:load); pCArchiveOut = new CArchive ( pExFile, Archive:store);第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.4 CArchive类和类和CSocketFile类类图图5.3 5.3 CSocketCSocket、CArchiveCArchive和和CSocketFileCSocketFile类在传输数据时的作用类在传输数据时的作用 第5章 MFC WinSockMFC WinSock类的编程类的编程5.2.5 关闭套接字和清除相关的对象关闭套接字和清除相关的对象资源释放:资源释放:套节字对象:套节字对象:u调用调用CloseClose() () 释放。释放。其他对象:其他对象:u包括包括CArchiveCArchive对象、对象、CSocketFileCSocketFile对象和对象和CSocketCSocket对象,可以将它们销毁;对象,可以将它们销毁;u可以不作处理,程序终止时,自动调用对象可以不作处理,程序终止时,自动调用对象的析构函数,从而释放占用的资源。的析构函数,从而释放占用的资源。第5章 MFC WinSockMFC WinSock类的编程类的编程5.3 CSocket类的编程模型类的编程模型 下面给出针对流式套接字的下面给出针对流式套接字的CSocketCSocket类的编类的编程模型。分为服务器端和客户端。程模型。分为服务器端和客户端。1、服务器端CSocket sockServ; sockServ.Create( nPort ); sockServ.Listen();/ 启动监听。启动监听。CSocket sockRecv; / 服务器端连接套接字服务器端连接套接字 sockServ.Accept( sockRecv); CSockFile* file ;第5章 MFC WinSockMFC WinSock类的编程类的编程5.3 CSocket类的编程模型类的编程模型file = new CSockFile( &sockRecv ); CArchive* arIn, arOut;arIn = CArchive ( &file, CArchive:load); arOut = CArchive( &file, CArchive:store);arIn dwValue; / 数据输入。数据输入。adOut dwValue; adOut dwValue; sockClient.Close();第5章 MFC WinSockMFC WinSock类的编程类的编程上节课小结上节课小结1 1、两个套接字类:、两个套接字类: 微软的微软的 MFCMFC提供了两个套接字类,在不同的层提供了两个套接字类,在不同的层次上对次上对Win Socket APIWin Socket API函数进行了封装,为编写网函数进行了封装,为编写网络通信程序,提供了两种编程模式:络通信程序,提供了两种编程模式:uCAsyncSocketCAsyncSocket类类uCSocketCSocket类类第5章 MFC WinSockMFC WinSock类的编程类的编程上节课小结上节课小结2 2、两个类的区别与联系:、两个类的区别与联系: CAsyncSocketCAsyncSocket类:类:在低层次上对在低层次上对Win Sockets APIWin Sockets API进行了进行了封装。封装。u它的成员函数和它的成员函数和Windows Sockets APIWindows Sockets API的函数调用直的函数调用直接对应。接对应。u一个一个CAsyncSocketCAsyncSocket对象代表了一个对象代表了一个WindowsWindows套接字;套接字;u将与套接字相关的将与套接字相关的WindowsWindows消息变为类的回调函数。消息变为类的回调函数。 CSocketCSocket类:类:从从CAsyncSocketCAsyncSocket类派生类派生uCSocketCSocket结合结合archivearchive类来使用套接字类来使用套接字。u管理了通信的许多方面,如管理了通信的许多方面,如字节顺序问题和字符串字节顺序问题和字符串转换问题转换问题。u提供了阻塞提供了阻塞的工作模式。的工作模式。第5章 MFC WinSockMFC WinSock类的编程类的编程上节课小结上节课小结CAsyncSocketCAsyncSocket能产生的消息及对应的处理过程:能产生的消息及对应的处理过程:uvirtual void virtual void OnReceiveOnReceive(int(int nErrorCodenErrorCode); ); 对应对应 FD_READFD_READ事件事件uvirtual void virtual void OnSendOnSend(int(int nErrorCodenErrorCode); ); 对应对应 FD_WRITEFD_WRITE事件事件uvirtual void virtual void OnAcceptOnAccept(int(int nErrorCodenErrorCode); ); 对应对应 FD_ACCEPTFD_ACCEPT事件事件uvirtual void virtual void OnConnectOnConnect(int(int nErrorCodenErrorCode); ); 对应对应 FD_CONNECTFD_CONNECT事件事件uvirtual void virtual void OnCloseOnClose(int(int nErrorCodenErrorCode); ); 对应对应 FD_CLOSE FD_CLOSE 事件事件uvirtual void virtual void OnOutOfBandDataOnOutOfBandData(int(int nErrorCodenErrorCode); ); 对应对应 FD_OOB FD_OOB 事件事件第5章 MFC WinSockMFC WinSock类的编程类的编程上节课小结上节课小结图图5.3 5.3 CSocketCSocket、CArchiveCArchive和和CSocketFileCSocketFile类在传输数据时的作用类在传输数据时的作用 第5章 MFC WinSockMFC WinSock类的编程类的编程5.4 5.4 CAsyncSocketCAsyncSocket类的应用实例类的应用实例第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.1 5.4.1 实现目标实现目标一个简单的聊天室:一个简单的聊天室:u程序采用程序采用C/SC/S模式,分为客户端程序和服务模式,分为客户端程序和服务器端程序器端程序 。u服务器只能支持一个客户,实际是一个服务器只能支持一个客户,实际是一个点对点对点通信点通信的程序的程序 。u客户端和服务器通过网络交换聊天的字符串客户端和服务器通过网络交换聊天的字符串内容内容 ,并在窗口的列表框中显示。,并在窗口的列表框中显示。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.2 5.4.2 创建客户端应用程序创建客户端应用程序1 1使用使用MFC AppWizardMFC AppWizard创建客户端应用程序框架。创建客户端应用程序框架。第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例2 2为对话框界面添加控件对象为对话框界面添加控件对象第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例3 3为对话框中的控件对象定义成员变量为对话框中的控件对象定义成员变量第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例4 4创建从创建从CAsyncSocketCAsyncSocket类继承的派生类类继承的派生类n为了能够捕获为了能够捕获并响应并响应socketsocket事事件,应创建用户件,应创建用户自己的套接字类自己的套接字类 ,它应当从,它应当从CAsyncSocketCAsyncSocket类类派生,还能将套派生,还能将套接字事件传递给接字事件传递给对话框,以便执对话框,以便执行用户自己的事行用户自己的事件处理函件处理函数。数。第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例n为套接字类添加响应消息的事件处理成员函数为套接字类添加响应消息的事件处理成员函数OnConnectOnConnect( ( ) )OnReceiveOnReceive( ( ) )OnCloseOnClose( )( )第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例n为套接字类添加一般的成员函数和成员变量为套接字类添加一般的成员函数和成员变量CTalkcDlgCTalkcDlg * *m_pDlgm_pDlg; ;Void Void SetParentSetParent(CTalkcDlg(CTalkcDlg * *m_pDlgm_pDlg););第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例n手工添加其他代码手工添加其他代码 对于对于MySocket.hMySocket.h,应在文件开头,添加对于此应,应在文件开头,添加对于此应用程序对话框类的声明。用程序对话框类的声明。class class CTalkcDlgCTalkcDlg; ;对于对于MySocket.cppMySocket.cpp,有四处添加:,有四处添加: 应在文件开头,添加包含文件说明。应在文件开头,添加包含文件说明。#include “#include “TalkcDlg.hTalkcDlg.h” 在构造函数中,添加对于对话框指针成员变量的在构造函数中,添加对于对话框指针成员变量的初始化代码:初始化代码:CMySocketCMySocket:CMySocketCMySocket() () m_pDlgm_pDlg = NULL; = NULL; 第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例 在析构函数中,添加对于对话框指针成员变量的在析构函数中,添加对于对话框指针成员变量的初始化代码:初始化代码:CMySocketCMySocket:CMySocketCMySocket() () m_pDlgm_pDlg = NULL; = NULL; 为成员函数为成员函数setParentsetParent和事件处理函数和事件处理函数OnConnectOnConnect,OnCloseOnClose和和OnReceiveOnReceive添加代码。添加代码。第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例5 5为对话框类添加控件对象事件的响应函数为对话框类添加控件对象事件的响应函数第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例6 6为为CTalkcDlgCTalkcDlg对话框类添加其它的成员函数和对话框类添加其它的成员函数和成员变量成员变量成员变量:成员变量:CMySocketCMySocket m_sConnectSocketm_sConnectSocket; ;/与服务器端连接的套接字与服务器端连接的套接字成员函数:成员函数:void void OnCloseOnClose(); / (); / 用来处理与服务器端的通信。用来处理与服务器端的通信。void void OnConnectOnConnect();();void void OnReceiveOnReceive();(); 第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例7 7手工添加的代码手工添加的代码 在在CTalkcDlgCTalkcDlg类的类的talkcDlg.htalkcDlg.h中添加对中添加对MySocket.hMySocket.h的包含命令,来获得对于套接字支持:的包含命令,来获得对于套接字支持: #include “#include “MySocket.hMySocket.h” 在在CTalkcDlgCTalkcDlg对话框类的对话框类的talkcDlg.cpptalkcDlg.cpp中添加对于中添加对于控件变量的初始化代码:控件变量的初始化代码:BOOL BOOL CTalkcDlg:CTalkcDlg:OnInitDialogOnInitDialog()() m_strServNamem_strServName=“=“localhostlocalhost”; / ”; / 服务器名服务器名 m_nServPortm_nServPort=1000; / =1000; / 服务端口服务端口 UpdateData(FALSEUpdateData(FALSE); / ); / 更新用户界面更新用户界面m_sConnectSocket.SetParent(thism_sConnectSocket.SetParent(this););第5章 MFC WinSockMFC WinSock类的编程类的编程CAsyncSocketCAsyncSocket类的应用实例类的应用实例8 8添加事件函数和成员函数的代码添加事件函数和成员函数的代码 主要在主要在CTalkcDlgCTalkcDlg对话框类的对话框类的talkcDlg.cpptalkcDlg.cpp中和中和CMySocketCMySocket类的类的Mysocket.cppMysocket.cpp中,添加用户自己的事中,添加用户自己的事件函数和成员函数的代码件函数和成员函数的代码 ,要注意,这些函数的框,要注意,这些函数的框架已经在前面的步骤中,由架已经在前面的步骤中,由VC+ VC+ 的向导生成,只要的向导生成,只要将用户自己的代码填入其中即可。将用户自己的代码填入其中即可。9 9进行测试进行测试第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.3 5.4.3 客户端程序的类与消息驱动客户端程序的类与消息驱动图图5.18 TalkcTalkc客户端程序的类与消息驱动的关系客户端程序的类与消息驱动的关系 第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.4 5.4.4 客户端程序的主要功能的代码和分析客户端程序的主要功能的代码和分析1 1应用程序类应用程序类CTalkcAppCTalkcApp对应的文件对应的文件 应用程序类应用程序类CTalkcAppCTalkcApp,对应的文件是,对应的文件是talkc.htalkc.h和和talkc.cpptalkc.cpp; talkc.htalkc.h定义了定义了CTalkcAppCTalkcApp类,类, talkc.cpptalkc.cpp是该类的实现代码,完全由是该类的实现代码,完全由VC+VC+自动自动创建,用户不必作任何改动。创建,用户不必作任何改动。2 2派生的套接字类派生的套接字类CMySocketCMySocket对应的文件对应的文件 CMySocketCMySocket类对应类对应MySocket.hMySocket.h和和MySocket.CPPMySocket.CPP文文件件第5章 MFC WinSockMFC WinSock类的编程类的编程3 3对话框类对话框类CTalkcDlgCTalkcDlg对应的文件对应的文件 对话框类对话框类CTalkcDlgCTalkcDlg,对应的文件是,对应的文件是talkcDlg.htalkcDlg.h和和talkcDlg.cpptalkcDlg.cpp4 4其他文件其他文件 对于为对于为talkctalkc工程创建的其他文件,如工程创建的其他文件,如stdafx.hstdafx.h和和stdafx.cppstdafx.cpp,以及,以及Resource.hResource.h和和talkc.rctalkc.rc都不需要作都不需要作任何处理。任何处理。 第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.5 5.4.5 创建服务器端程序创建服务器端程序 同样利用可视化语言的集成开发环境同样利用可视化语言的集成开发环境(IDE)(IDE)来创建服来创建服务器端应用程序框架。步骤是:务器端应用程序框架。步骤是:1.1.使用使用MFC AppWizardMFC AppWizard创建服务器端应用程序框架。创建服务器端应用程序框架。2.2.为对话框界面添加控件对象为对话框界面添加控件对象3.3.为对话框中的控件对象定义相应的成员变量为对话框中的控件对象定义相应的成员变量4.4.创建从创建从CAsyncSocketCAsyncSocket类继承的派生类类继承的派生类5.5.为对话框类添加控件对象事件的响应函数为对话框类添加控件对象事件的响应函数6.6.为为CTalksDlgCTalksDlg对话框类添加其它的成员函数和成员变量对话框类添加其它的成员函数和成员变量7.7.手工添加的代码手工添加的代码8.8.添加事件函数和成员函数的代码添加事件函数和成员函数的代码9.9.进行测试。进行测试。第5章 MFC WinSockMFC WinSock类的编程类的编程5.4.6 服务器端程序的流程和消息驱动 图图5.20 Talks服务器端程序的类与消息驱动的关系服务器端程序的类与消息驱动的关系 第5章 MFC WinSockMFC WinSock类的编程类的编程5.5 5.5 CSocketCSocket实现聊天室实现聊天室服务器端要点:服务器端要点:u多个客户端可以同时连接一个服务器端;多个客户端可以同时连接一个服务器端;u从从CSocketCSocket类上继承两个派生类;分别用于监听类上继承两个派生类;分别用于监听和客户端连接和客户端连接 P175P175u套接字类里定义两个套接字类里定义两个ArchieveArchieve对象指针和一个对象指针和一个CSockFileCSockFile对象指针对象指针 P175P175u对话框类里定义两个对话框类里定义两个ArchieveArchieve对象指针和一个对象指针和一个CSockFileCSockFile对象指针对象指针 P188P188u服务器利用套接字数组保存各个连接的套接字;服务器利用套接字数组保存各个连接的套接字;CPtrListCPtrList m_connListm_connList; ; P176P176u定义一个消息类定义一个消息类CMsgCMsg完成对收发信息的存取完成对收发信息的存取P190P190
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号