友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

VC语言6.0程序设计从入门到精通-第59部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


    o  s:准备接收数据的套接字。  

    o  buf :指向即将接收数据的字符缓冲区的指针。  

    o  len :缓冲区的大小。  

    o  flags:指定传输控制方式,取值可为 0、MSG_PKKE 和 MSG_OOB ,或者是这些取值 

     进行按位或运算的结果 。其中,0 表示无特殊行为;MSG_PKKE 表示把数据从接收端 

      口复制到接收缓冲区中,并且没有从系统缓冲区中将数据删除;MSG_OOB 表示数据 

      是带外发送的。  

    如果接收成功,则返回接收的字节数,如果失败则返回 SOCKET_ERROR。  



11。3    WinSock 类  



    在上一节中简单介绍了直接利用 WinSock API 进行网络传输的基本步骤以及主要函数的 

使用方法,而实际利用 Visual  C++  6。0 开发网络应用程序的时候,很少直接利用这些 API 进 

行编程,因为 MFC  已经把这些 API 都封装到 MFC 提供的类中了。本节将详细介绍在网络编 

程中经常用到的 MFC 提供的两个类,即 CAsyncSocket 类和 CSocket 类。它们的继承关系如 

图 11…1 所示。  



                                                



                   图 11…1    CAsyncSocket 类和 CSocket 类的继承关系  



11。3。1    CAsyncSocket 类  



    CAsyncSocket 类在很低的级别上封装了 Windows Socket API ,该类可以使程序员用面向 

对象的方法进行 Socket 编程,而且可以非常方便地调用其他 MFC 对象。这个类要求程序员 

对 Socket 编程有较为深入的了解,要面对和在直接使用 Windows Socket API 进行程序设计时 

一样的问题,如阻塞处理、网络字节顺序等。因为 CAsyncSocket 类几乎是一一对应地封装了 

Windows Socket API ,因此具有直接调用 WinSock API 的灵活性。  

    要使用一个 CAsyncSocket 对象,则先调用它的构造函数,然后调用 Create()函数,以创 

建一个套接字句柄(SOCKET 类型)。CAsyncSocket 对象既可以在栈中,也可以在堆中。对 



                                                                    ·285 ·  


…………………………………………………………Page 297……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



于一个服务器套接字调用  Listen()成员函数进行监听,对于一个客户套接字调用  Connect()成 

员函数来请求连接。在接收一个连接请求时,服务器套接字应该调用一个  Accept() 函数来接 

收连接请求。完成之后,如果 CAsyncSocket 对象在栈中构造,则当对象超出范围时,会自动 

调用析构函数;如果是在堆上被创建的,必须调用 delete 来删除此对象。  

    CAsyncSocket 类的主要成员函数如表 11…3 所示。  



    表 11…3               CAsyncSocket 类主要成员函数及说明  



         函数                                    说明  

 CAsyncSocket         构造函数  

 Create               创建一个 Socket  

 Attach               对 CAsyncSocket 对象附加套接字句柄  

 Detach               从 CasyncSocket 对象除去套接字句柄  

 FromHandle           返回 CasyncSocket 对象的指针,给出套接字句柄  

 GetLastError         获得上一次运行失败的状态  

 GetPeerName          获得与套接字连接的对等套接字的地址  

 GetSockName          获得套接字的本地名  

 GetSockOpt           获得套接字选项  

 SetSockOpt           设置套接字选项  

 Accept               接受套接字上的连接  

 AsyncSelect          请求对于套接字的事件通知  

 Bind                 给套接字绑定本地地址  

 Close                关闭套接字  

 Connect              与对等套接字建立连接  

 IOCtl                控制套接字模式  

 Listen               建立套接字,侦听即将到来的连接请求  

 Receive              从套接字接收数据  

 ReceiveFrom          接收数据报并且存储资源地址  

 Send                 给连接套接字发送数据  

 SendTo               给特定目的地发送数据  

 ShutDown             使套接字上的 Send 和/或 Receive 调用无效  

 OnAccept             通知侦听套接字,它可以通过调用 Accept ,接受挂起连接请求  

 OnClose              通知套接字,关闭对它的套接字连接  

 OnConnect            通知连接套接字,连接尝试已经完成,无论成功或失败  

 OnOutOfBandData      通知接收套接字,在套接字上有带外数据读入,通常是忙消息  

 OnReceive            通知侦听套接字,通过调用 Receive 恢复数据  

 OnSend               通知套接字,通过调用 Send,它可以发送数据  



    除了上面的成员函数,CAsyncSocket 类还有一个数据成员 m_hSocket ,它是一个 SOCKET 

句柄,记录了 CAsyncSocket 类上附加的套接字。  



11。3。2    CSocket 类  



    CSocket 类是  CAsyncSocket 类的派生类,它最大的特点是提供了可以同                  CArchive 和 

CSocketFile  这两个类协同工作的接口。其中  CArchive  类是一个存档类,它是将用户的数据 

保存为永久性存储对象的一种技术,在此它是用于同 CSocketFile 类相关联而提供数据传输文 

件化的一种技术 。而 CSocketFile 类是一种特殊的文件对象,常用它来通过套接字进行数据的 

传递,它所提供的接口同普通文件类的接口基本上是一致的 。也就是说,用户在使用 CSocket 

类的时候,不必再像使用 CAsyncSocket 类时不得不面对一大堆繁琐的工作,而只需像读写一 



 ·286 ·  


…………………………………………………………Page 298……………………………………………………………

                                                            第 11 章    网络编程  



般文件一样直接进行数据的读取就可以了。本章主要讲述网络编程,因此本小节主要介绍 

CSocket 类,而 CArchive 类和 CSocketFile 类的相关信息请读者自行查阅相关资料。  



    1.CArchive 对象与串行化技术  



    CArchive 对象是 MFC  中专门帮助程序员处理归档对象的类,它最主要的作用就是把内 

存中的数据保存到永久存储介质中,这样程序员就不必担心使用的到底是套接字还是文件了。 

而为了实现 CArchive 与 CSocket 之间的连接,必须使用 CSocketFile 作为中间的转化媒质。 

在实际工作中 CSocketFile 对象负责连接到一个 CSocket 对象,而 CArchive 对象负责管理缓 

冲区。当发送归档对象的缓冲区被填满时,相关的 CSocketFile 对象会将缓冲区的内容取出, 

并清空与套接字相关的归档缓冲区。当接收归档对象的缓冲区被填满时,CSocketFile 对象将 

停止读出直到缓冲区可用。  



    2 .用 CSocket 类的编程步骤  



    用 CSocket 类进行网络编程的基本步骤如下。  

    o  构造服务器和客户机套接字对象。  

    o  调用 Create()函数创建套接字。  

    o  服务器调用  Listen() 函数监听客户机的连接请求;客户机调用 Connect()函数向服务器 

      发出连接请求。  

    o  服务器监听到客户机的连接请求时,先创建一个新的套接字,然后调用  Accept() 函数 

     接收客户机的连接请求。  

    o  服务器和客户机的套接字对象分别建立一个与之联系的 CSocketFile 对象。  

    o  服务器和客户机的套接字对象分别创建一个与 CSocketFile 相联系的 CArchive 对象, 

                        

      以便进行数据传输。 

    o  使用 CArchive 对象在服务器和客户机套接字之间进行数据传输。  

    o  当任务完成后,销毁 CArchive、CSocketFile 和 CSocket 对象。  



    注意:由于 CArchive 对象只能单向传送数据,所以在实际使用的时候必须定义两个 CArchive 对 



        象,分别用于数据的发送和接收。  



    3 .CSocket 类的主要成员函数  



    CSocket 类是从 CAsyncSocket 类继承来的,除了 CAsyncSocket 类的成员函数,CSocket 

类还主要有以下成员函数,如表 11…4 所示。  



    表 11…4                      CSocket 类主要成员函数及说明  



         函数                                  说明  

 CSocket              构造一个 CSocket 对象  

 Create               创建一个 Socket  

 IsBlocking           确定一个阻塞调用是否在进行中  

 FromHandle           返回一个指向 CSocket 对象的指针,给出一个 Socket 句柄  

 Attach               将一个 Socket 句柄与一个 CSocket 对象连接  

 CancelBlockingCall   取消一个当前在进行中的阻塞调用  

 OnMessagePending     当等待完成一个阻塞调用时调用此函数来处理未处理的消息  



                                                                    ·287 ·  


…………………………………………………………Page 299……………………………………………………………

Visual C++ 6。0 程序设计从入门到精通  



11。4    网络编程的实现  



   前面介绍了很多关于 Windows 网络编程的知识,也详细介绍了 WinSock 类。接下来,本 

节将按照上小节所说的编程步骤,利用 CSocket 类编写一个网络聊天程序。相信通过这个程 

序,读者会对 CSocket 的基本应用有更加深入的认识。  



实例 11…1:网络聊天程序实例。源代码在光盘中“11实例 11…1”目录下。  



11。4。1    程序设计的基本任务  



   为了让读者易于理解而又能体现出网络编程的一般步骤,本程序抛弃很多网络应用程序 

的辅助功能,只实现网络聊天系统的基本功能。该系统包括服务器和客户端两部分,服务器 

允许多个客户端连接,连接到服务器的客户端可以聊天,聊天的内容会在服务器和每个客户 

端显示出来,同时,在服务器上还可以显示出每个客户端的基本信息,比如登录时间和 IP 等。  



11。4。2    服务器端程序设计  



   1.设计概述  



   在进行服务器端程序设计之前,首先要考虑一下消息在程序中如何处理。在整个系统中, 

服务器和客户端的交互都是通过消息完成的,并且对于一般的网络应用程序来说,网络数据 

的有效封装有利于用户对网络通信的管理,也有利于在源程序的基础上作进一步的开发。因 

此在本程序中,会对消息进行简单的封装。  

   接下来考虑界面设计 。服务器端应该有两个窗口,分别显示各客户端的详细信息(如用 

户名、登录时间、IP 等)和用户的聊天信息。  

   关于程序流程在 11。3。2 节的第 2 小节已有说明。除此之外,在网络编程中还有很重要的 

一点,就是服务器和客户端双方要约定好信息的格式以及发送顺序,只有约定好这些,双方 

才知道对方所发信息的意义。其实这就是通常所说的协议的一个重要部分,在网络应用程序 

的设计中,协议是必不可少的,越是大型的网络应用程序,协议就越复杂。对于本例这个很 

小的程序,可以根据消息的类型(封装在消息类中)对消息进行分类,并且约定当用户登录 

或离开时,都要先发送用户名给服务器,然后再发送正式信息。这样通过消息的种类,服务 

器就能够知道当前消息是一般消息还是用户登录或离开的消息。如果是前者,就将其发送给 

每个客户端,并且在服务器界面将信息显示出来;如果是后者,则将登录或离开的用户名发 

送给各客户端,以使各客户端对用户列表更新,同时更新服务器端的用户列表。  

   最后,本程序采用文档…视图结构,视图负责显示,而数据的处理则通过文档类来实现。  



   2 .编写代码  



   (1)创建工程  

   新建一个 MFC 工程,取名为 ChatServer 。利用 AppWizard 创建 SDI 程序,在第一步中 



·288 ·  


…………………………………………………………Page 300……………………………………………………………

                                                                                  第 11 章    网络编程  



选择“Single Document”项,在第四步中选中“Windows Sockets ”复选框,如图 11…2 所示。 

在最后一步的“Base Class ”下拉列表中选择“ClistView ”作为基类,其他选项保持默认,单 

击“Finish ”按钮即可完成工程的创建,如图 11…3 所示。  



                                                                                                      



       图 11…2    选中“Windows Sockets ”复选框                           图 11…3    选择“ClistView ”作为基类  



     (2 )封装消息类  

     本程序中为消息建立一个类 CMsg,它的父类是 CObject 。在“ChatServer  classes ”上单 

击右键,在弹出的对话框中选择“New Class ”,如图 11…4 所示。在弹出的“New Class ”对话 

框中的“Class type ”下拉列表中选择“Generic Class ”项,在“Name ”栏中填写类名称 CMsg, 

在“Derived From ”栏中填写其父类名称 CObject,如图 11…5 所示。单击“OK ”按钮,弹出 

提示对话框,单击“确定”即可。  



                                                                                                 



               图 11…4    为工程新建一个类                                   图 11…5    新建消息类 CMsg  



     在类CMsg 的定义(文件“Msg。h ”)中加入宏DECLARE_DYNCREATE(CMsg) ,声明此 

宏可以使得由CObject继承来的类在程序运行的时候能够动态地创建。然后为其加入成员变量 

和成员函数,分别如表11…5和表11…6所示。  

       

       



                                                                                              ·289 ·  


…………………………………………………………Page 301……………………………………………………………
返回目录 上一页 下一页 回到顶部 1 2
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!