• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
张纯睿
博客园    首页    新随笔    联系   管理    订阅  订阅

CASyncSocket类和CSocket类编程

CASyncSocket类和CSocket类编程      
      简言之,CSOCKET是对SOCKET   API   的高级而又简单的包装,而CAsyncSocket的包装就相对低级,  
  要求程序员自己处理的细节多,但应用就更灵活,更接近API,

        CSocket派生于CAsyncSocket,支持同步操作。  
        CAsyncSocket封装Windows   Sockets   API  

         windows的socket默认是阻塞模式,CAsyncSocket是非阻塞模式,CSocket是非阻塞模式的阻塞socket.阻塞非阻塞可以通过ioctlsocket函数来设置。

   
   
    本文主要讲解以下内容  
    (1)CAsyncSocket类编程模式。  
    (2)CSocket类编程模式。  
    (3)CSocketFile类和CArchive类简介。  
    通过学习,可以掌握CAsyncSocket类和CSocket类的编程模式,了解CSocketFile类和  
  CArchive类。CAsyncSocket类逐个封装了Winsock函数,以前介绍过的Winsock函数在CAsyncSocket类  
  的成员函数中都可以找到它们对应的函数。一个CAsyncSocket对象就代表着一个Windows   Socket,  
  使用这个类进行网络编程,就要求程序员对网络通信和Socket编程模式有相当的了解,因为程序员  
  要自己编写程序处理阻塞、字节顺序以及Unicode与MBCS之间的转换等问题。  
    为使程序员可以更方便地编写Socket程序,MFC又给出了CSocket类。CSocket类是CAsyncSocket  
  类的派生类,它在继承了CAsyncSocket类的所有函数的同时提供了比CAsyncSocket类更高层的网络  
  编程接口。利用CSocket类和与之搭配的CSocketFile类以及CArchive类编写网络程序更加简单便利,  
  这主要是由于在CSocket类中提供了阻塞模式,因而可以利用CArchive进行同步操作。  
   
    提示:  
    在这里需要特别强调一下阻塞函数的概念,一个Socket可以处于“阻塞模式”或“非阻塞模式”,  
  当一个Socket处于“阻塞模式”时,它的阻塞函数(如send函数、recv函数之类的函数)直到其操  
  作完成后才会返回给程序控制权,而Socket的阻塞在此之前不能作其他操作。如果Socket处于“非  
  阻塞模式”(即异步模式),调用函数将会立即返回给程序控制权。  
   
    对于阻塞函数引起的错误,调用CAsyncSocket类的GetLastError成员函数时,将返回错误  
  WSAEWOULDBLOCK。而对于CSocket类,由于它有自己的阻塞管理,则不会出现该类错误代码,  
  CSocket类的许多成员函数都带有阻塞性质,但可以结合CArchive类处理。在Win32环境下,如果  
  要使用具有阻塞性质的Socket,应该将其放在单独的工作者线程中,充分利用多线程编程不干预其他  
  线程的便利。多线程编程的方法,可以使程序员充分利用CSocket类的阻塞管理方式,而不影响到用  
  户界面线程。  
    要在MFC中进行Socket编程,需要在应用程序类的Initlnstance中调用AfxSocketlnit初始化套  
  接字。如果使用AppWizard创建应用程序的基本框架时,选中了“WindowsSockets”复选框,那么将  
  自动添加初始化代码。  
   
   
  1   CAsyncSocket类编程模式  
   
    在用MFC进行Winsock编程时,使用CAsyncSocket类的优点为:可以轻松处理多个网络协议,  
  效率高,灵活性好;它的缺点则是需要程序员编写程序来处理诸如阻塞等情况,比较麻烦。  
   
    提示:  
    使用CAsyncSocket类和CSocket类编程,需要加载头文件afxsock.h。  
   
    以下为CAsyncSocket类的编程模式。  
    1)创建一个Socket  
    创建一个Socket分为两步,首先调用CAsyncSocket类的构造函数创建一个CAsyncSocket类的  
  对象;然后调用成员函数Create创建底层套接字。构造套接字时,对于服务器端的程序,需要用一  
  个众所周知的端口提供服务;而对于客户端程序,使用缺省的参数调用Create函数创建Socket即可。  
  以下是创建Socket的程序代码举例。  
  (1)服务器端程序:  
  CAsyncSocketServerSocket;  
  int   nPort=27;  
  ServerSocket.Create(nPort,SOCK_DGRAM);  
  以上程序在栈中创建了一个CAsyncSocket对象,并用调用该对象的Create函数创建了一个数据  
  报式套接字。  
  CAsyncSocket* pServer=newCAsyncSocket;  
  intnPort=27;  
  pServer->Create(nPort);  
  以上程序在堆中创建了一个CAsyncSocket对象,并用调用该对象的Create函数创建了一个字节  
  流式套接字,创建字节流式套接字的Create函数的第二个参数可省略。  
  (2)客户端程序;  
  CAsyncSocketClientSocket;  
  ClientSocket.Create();  
  以上程序在栈中创建了一个CAsyncSocket对象,并使用以缺省参数调用该对象的Create函数创  
  建了一个数据报式套接字。对于客户端程序的Socket采用Create函数的缺省调用,可以使套接字自  
  主地选择一个能够使用的端口。  
  为了进一步说明Create函数的用法,下面给出该函数的原型:  
  BOOLCreate(UINT nSocketPort=0,int nSocketType=SOCK_STREAM,longlEvent=FD_READ   |  
    FD_WRITE   |   FD_OOB   |   FD_ACCEPT   |   FD_CONNECT   |   FD_CLOSE,   LPCTSTR  
    lpszSocketAddress=NULL);  
  参数说明:  
  nSocketPort:为套接字指定的端口,缺省时将自动为套接字选择可用的端口。  
  nSocketType:套接字类型,默认为字节流方式,如果把该参数设为SOCK—DGRAM,将创建数  
  据报式套接字。  
  lEevent:该参数用于指定可以通知相关窗口的消息,缺省为列出的所有事件都将生成相应的消  
  息通知相关的窗口。  
  lpszSocketAddress:套接字的网络地址,缺省时为本机的网络地址。  
   
    提示:  
    MFC定义了一个内部的类CSocketWnd,   当调用Create函数创建一个套接字时,就会将该套接  
  字连接到一个窗口(CSoketWnd的对象),CAsyncSocket的DoCallBack函数为该窗口的回调函数。  
  这样,   当一个网络事件发生时,经过MFC的消息循环,DoCallBack函数会根据不同的事件调用相应  
  的消息处理函数。MFC将这些消息处理函数定义为虚函数,在编程时必须重载需要的消息处理函数。  
   
    2)客户端连接与服务端监听  
    对于客户端程序,需要调用Connect成员函数连接到服务器,如以下程序所示:  
  ClientSocket.Connect(addr,nPort);  
  参数说明:  
  addr:服务器地址,例如“202.12.15.1”或www.microsoft.com之类的网络地址。  
  nPort:服务器Socket端口号。  
  对于服务器端程序,需要调用Listen成员函数对Socket所在的端口进行监听,一旦收到连接请  
  求,则调用Accept成员函数开始接收,如以下程序所示:  
  ServerSocket.Listen();  
  ServerSocket.Accept(CAsyncSocket& rConnectedSocket);  
  Accept函数的参数为一个空的CAsyncSocket对象,即由CAsyncSocket的构造函数构造的还未调  
  用Create成员函数创建套接字的CAsyncSocket对象。  
   
    提示:  
    为了进一步说明Accept函数的用法,下面给出该函数的原型:  
  virtual   BOOL   Accept(CAsyncSocket& rConnectedSocket,SOCKADDR   lpSockAddr=NULL,int  
  lpSockAddrLen=NULL);  
  (1)调用其他的CasyncSocket成员函数进行通信管理。  
  (2)   网络通信结束后,对于在栈中创建的CAsyncSocket对象,如果对象超出定义的范围时将自  
  动调用析构函数释放相关资源;对于在堆中创建的CAsyncSocket,需要调用delete操作销毁对象符  
  释放相关资源。  
    2   CSOCket类编程模式  
   
    CSocket类是CAsyncSocket类的派生类,它们都是从CObject类继承下来的.CSocket类代表  
  了比CAsyncSocket类更高层次的网络接口抽象。CSocket可以和CSocketFile类、CArchive类一  
  起管理数据的接收和发送。  
  以下为CSocket类的编程模式:  
  (1)创建Socket  
  ●服务器端程序:  
  CSocketsockSrvr;  
  sockSrvr.Create(nPort);   //用指定端口创建套接字  
  ●客户端程序:  
  CSocketsockClient;  
  sockClient.Create();   //用缺省的端口创建套接字  
  (2)连接  
  ●服务器端程序:  
  sockSrvr.Listen();   服务器端程序对指定连接端口进行监听  
  CSockersockRecv;   //创建一个空的CSocket对象  
  sockSrvr.Accept(sockRecv);   //接受客户端的连接请求  
  ●客户端程序:  
  sockClient.Connect(strAddr,nPort);//连接指定地址的服务器(参数strAddr中指定)  
  (3)数据传输  
  ●服务器端程序:  
  CSocketFile file(&sockRecv);  
  //创建与CSocket类的对象相连接的CSoeketFile类对象  
  CArchive arin(&file,CArchive::load);  
  //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储将要发送的数据  
  CArchive arout(&file,CArchive::load);  
  //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储接收的数据  
  arin>>dwValue;   //发送数据dwValue  
  arout<<dwValue;   //接收数据dwValue  
  ●客户端程序:  
  CSocketFile file(&sockClient);  
  //创建与CSocket类的对象相连接的CSocketFile类对象  
  CArchive arin(&file,CArchive::load);  
  //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储将要发送的数据  
  CArchive arout(&file,CArchive::load)  
  //创建与CSocketFile类的对象相连接的CArchive类对象,用于存储接收的数据  
  arin>>dwValue;   //发送数据dwValue  
  arout<<dwValue;   //接收数据dwValue  
  (4)   网络通信结束后,对于在栈中创建的CSocket对象、CArchive对象、CSocketFile对象,如  
  果对象超出定义的范围时将自动调用析构函数释放相关资源;对于在堆中创建的对象,需要调用delete  
  操作销毁对象符释放相关资源。  
   
    提示:  
    关于CArchive类和CSocketFile类的知识将在后面的小节中介绍,在这里只需要有个大致的了解  
  即可。  
   
    除了利用CSocketFile类的对象和CArchive类的对象辅助数据传输外,利用CSocket的成员函数  
  同样可以实现数据的网络传输。  
  下面为利用CSocket成员函数的编程模式:  
  (1)创建Socket  
  ●服务器端程序:  
  CSoeket soekSrvr;  
  sockSrvr.Create(nPort);   //用指定端口创建套接字  
  ●客户端程序:  
  CSocket sockClient;  
  sockClient.CreateO;   //用缺省的端口创建套接字  
  (2)连接  
  ●服务器端程序:  
  sockSrvr.Listen();   //服务器端程序对指定连接端口进行监听  
  CSocket sockRecv;"创建一个空的CSocket对象  
  sockSrvr.Accept(sockRecv);   //接受客户端的连接请求  
  ●客户端程序:  
  sockClient.Connect(strAddr,nPort)//连接指定地址的服务器(参数strAddr中指定)  
  (3)数据传输  
  ●服务器端程序:  
  sockRecv.SendTo(esSendText,csCounts,nPort,strAddr);  
  //调用SendTo成员函数将csSendText指向的缓冲区数据传送到参数strAddr所代表的  
  //网络地址。  
  ●客户端程序:  
  sockClient.RecieveFrom(csRecieveText,csCounts,strAddr,nPort);  
  //调用ReciveFrom成员函数将从strAddr所代表的网络主机传送来的数据保存在//csReciveText  
  指向的缓冲区中。  
  (4)通话结束处理  
  ●服务器端程序:  
  sockSrvr.Close();  
  sockRecv.Close();  
  ●客户端程序,  
  sockClient.C!ose();  
  此外,还要删除相应的CSocket对象,释放资源


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/carl2380/archive/2010/08/24/5833708.aspx

posted @ 2011-06-29 15:05  张纯睿  阅读(713)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3