版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1 1第10章 面向对象技术10.1 面向对象概述面向对象概述10.2 MFC CAsyncSocket类网络编程类网络编程10.3 MFC CSocket类网络编程类网络编程10.4 多媒体通讯编程多媒体通讯编程小结小结2 2除了采用链接库的封装方法,还有一种更具有优势的封装方法面向对象类封装。面向对象的编程技术采用与传统面向过程的编程方法不同的思想,曾经在单机的运用程序设计中得到了有效验证。同样,在网络编程中,也可以提高程序的复用性和可读性。本章首先从面向对象的封装、承继和多态入手,在此根底上引见了两种MFC提供的两种套接字类,为了深化引见面向对象网络编程的益处,将其运用于多媒体通讯编程。
2、两种套接字类是对传统API函数的封装,将二者比较进展学习有益于对本章内容的掌握。3 3在传统的面向过程的程序设计中:程序=算法+数据构造,这里的算法实践上就是功能笼统。在面向过程的程序设计中,程序是模块化的,模块是分层次的,层与层之间是一个从上往下的调用关系,如图10-1。10.1 面向对象概述面向对象概述4 4图10-1 面向过程的程序组织5 5图10-2 面向对象的程序组织6 6然而,功能笼统是困难的,而且很难全面。一旦要处理的问题发生一点小变化,功能块就要重编,而一个功能块又被多个上层模块调用,它们的要求有的变了、有的没变,这就给重编带来极大的困难。详细的缺陷表现为:利用传统的面向过程的
3、程序开发,即使开发一个简单的Windows运用程序也需求对编程原理有很深化的认识,需求手工编写冗长的代码;程序的出错率是随着代码长度的添加呈几何级数增长的,当程序长度逐渐膨胀时,调试程序也会变得越来越困难。7 7鉴于面向过程的程序设计存在的缺陷,20世纪90年代流行起来的面向对象的程序设计将面向过程的程序设计中心思想交换为:程序=对象+对象+对象,其中对象=算法+数据构造。这样,程序变为一个个封装对象的结合体,而对象由严密结合在一同的算法和数据构造组成,对象中有数据和对数据的操作,具有完好的个体功能,如图10-2所示。类是用来定义对象的一种笼统数据类型,它是产生对象的模板。类可以以为是一种特殊
4、的构造体,根本上说C+对C言语的最重要的改良就是添加了“类这种数据类型。8 810.1.1 封装封装封装即是将某种东西包装隐藏起来,让外界封装即是将某种东西包装隐藏起来,让外界无法直接运用,只能经过某些特定的方式才干访无法直接运用,只能经过某些特定的方式才干访问。封装是面向对象的根底,它将底层的元素组问。封装是面向对象的根底,它将底层的元素组合起来构成新的高层次实体,本质上是一种信息合起来构成新的高层次实体,本质上是一种信息隐藏技术。面向对象是以类为单位进展代码的封隐藏技术。面向对象是以类为单位进展代码的封装。装。在前面面向过程的编程中,我们曾经知道函在前面面向过程的编程中,我们曾经知道函数也
5、是封装的一种方式。函数将所执行的细节行数也是封装的一种方式。函数将所执行的细节行为封装在函数本身这个更大的实体中,被封装的为封装在函数本身这个更大的实体中,被封装的元素隐藏了它们的实现细节元素隐藏了它们的实现细节(可以调用函数却不能可以调用函数却不能访问它所执行的语句访问它所执行的语句)。与之类似,类也是一个封。与之类似,类也是一个封装的实体,它代表假设干成员的聚集,它们中的装的实体,它代表假设干成员的聚集,它们中的大多数同样隐藏了实现该类型的成员。大多数同样隐藏了实现该类型的成员。9 9定义一个类时也就定义了一个类型,用这个类型可以定义一个对象(类的用户),计算机系统会为定义的对象分配存储空
6、间。类由类成员组成,成员又由成员变量和成员函数组成,分别代表类的特性和行为。成员又划分为三种类型,即public、private、protected,这三种类型实现了对类封装的分层次的信息隐藏。public成员:该类型成员可以被运用该类型的一切代码访问。private成员:该类型成员只可被本类其他类成员或友元(friend)访问,子类不可承继和访问。10 10protected成员:该类型成员可被其他类成员或友元访问,也可被子类承继和访问。对象只能访问public成员。这三种成员类型的访问关系,可以用下面的程序进展阐明。class Aprivate: int a;public: int b;1
7、1 11 void f1() a=0; b=1; c=2; protected: int c;class B: public Apublic:int d;void f2() c=0;12 12根据成员public、private、protected的性质,对A、B对象的访问A ca、ca.b=1、ca.f1()、B cb、cb.b=2、cb.d=3、cb.f1()、cb.f2()均是合法的。对于ca.a、ca.c、cb.a、cb.c的访问都不合法。13 1310.1.2 承继承继通俗地讲,后代具有源自祖先的某些特点就通俗地讲,后代具有源自祖先的某些特点就叫承继。假设只需封装,那么非面向对象言语
8、的叫承继。假设只需封装,那么非面向对象言语的构造体也能做到,承继那么把代码复用提升到了构造体也能做到,承继那么把代码复用提升到了一个新高度。面向对象的承继包含两层含义,即一个新高度。面向对象的承继包含两层含义,即继续和开展。不继续父类的特性那么失去承继的继续和开展。不继续父类的特性那么失去承继的本义,子类不开展出新的特性那么失去存在意义本义,子类不开展出新的特性那么失去存在意义(沿用父类即可沿用父类即可)。承继是一种树状的层次关系,。承继是一种树状的层次关系,子类在承继祖先类的成员变量和成员函数的同时,子类在承继祖先类的成员变量和成员函数的同时,也可以定义本人的成员变量和成员函数。也可以定义本
9、人的成员变量和成员函数。14 14子类承继父类有三种方法,即公共、私有和受维护承继(为了区别public、private和protected,这里运用中文),这三种承继方法会使得父类中的成员信息隐藏特性发生变化,详细如下:公有承继:基类的成员坚持本人的访问级别,基类的public成员为派生类的public成员,基类的protected成员为派生类的protected成员。私有承继:基类的一切成员在派生类中变为private成员。受维护承继:基类的public和protected成员在派生类中变为protected成员。15 15承继的本质就是实现代码重用,因此承继机制可以缩短软件的开发周期,加
10、快编程速度。16 1610.1.3 多态多态为了添加类的承继灵敏性,面向对象技术提为了添加类的承继灵敏性,面向对象技术提出了类的多态出了类的多态(动态绑定动态绑定)特性,简称多态性。多特性,简称多态性。多态性是指发出的同样音讯被不同类型的对象接纳态性是指发出的同样音讯被不同类型的对象接纳有能够导致完全不同的行为。利用多态性技术可有能够导致完全不同的行为。利用多态性技术可以用同一个函数名的函数,实现完全不同的功能,以用同一个函数名的函数,实现完全不同的功能,这与客观世界的现实完全相符。这与客观世界的现实完全相符。多态是面向对象系统的重要特性,对于同一多态是面向对象系统的重要特性,对于同一个音讯可
11、以根据发送音讯的对象的不同采用多种个音讯可以根据发送音讯的对象的不同采用多种不同的处置方式。多态性主要是依托不同的处置方式。多态性主要是依托virtual(虚函虚函数数)实现的,实现的,C+中在成员函数的最前面加上关键中在成员函数的最前面加上关键字字virtual就可以将该函数设置为虚函数,在子类就可以将该函数设置为虚函数,在子类中可以运用一样的函数名对其进展重新定义。中可以运用一样的函数名对其进展重新定义。17 17对于在父类中无法被详细定义的虚函数,可以将其定义为纯虚函数(即函数定义后再加上“=0的阐明)。纯虚函数普通不在(通常也无法在)父类中详细定义,仅在子类中详细定义,这种定义很有用,
12、例如:“动物这个类可以派生出“昆虫、“哺乳动物、“鸟等子类,但是在动物类本身中无法详细定义“吃这个函数,因此需将eat()定义为纯虚函数,如下:class animal public: virtual void eat()=0;18 18有纯虚函数的类不能直接生成对象,即上述的类的“animal a;就不合法。需留意的是,虚函数只在public和protected中定义,针对父类中能够在子类中修正的函数才适宜。构造函数因其里面要插入对虚函数表指针的初始化语句,因此也不能声明为虚函数。通常,尽能够地把函数声明为虚函数是一个好的编程习惯,这样做添加了子类设计的自在度。在MFC(参见2.8.2节)中
13、,微软利用这个类库践行了面向对象网络编程的优越性,10.2节和10.3节将分别进展引见。鉴于篇幅缘由,关于更多的面向对象的知识请参阅其他书籍,这里仅作概念性引见。19 19如前所述,MFC封装了大约有100多个类,直接与套接字编程有关的主要是两个类,即CAsyncSocket和CSocket(还有一个从CSocket派生的CCeSocket类,主要用于WinCE平台,这里不记在内),从本节开场将分别进展引见。10.2 MFC CAsyncSocket类网类网络编程络编程202021 2110.2.1 CAsyncSocket类类CAsyncSocket派生自派生自CObject类类(构造如图构
14、造如图10-3所示所示),利用它可以方便地处置有关网络行为的,利用它可以方便地处置有关网络行为的通知音讯。通知音讯。CAsyncSocket封装了低层的封装了低层的WinSock API,它在原有的,它在原有的WinSock函数的根底上提供了函数的根底上提供了一些面向对象的特性,如衔接、接纳事件。与其一些面向对象的特性,如衔接、接纳事件。与其他面向对象的他面向对象的C+插口类不同,插口类不同,CAsyncSocket类类所提供的独一的笼统就是将与套接字相联络的所提供的独一的笼统就是将与套接字相联络的Windows音讯以回调函数的方式表示,可以说音讯以回调函数的方式表示,可以说CAsyncSoc
15、ket类是用于异步类是用于异步WinSock调用的一个调用的一个包容类。包容类。2222缺省情况下,运用该类创建的Socket是非阻塞的Socket,一切操作都会立刻前往,假设没有得到结果,前往WSAEWOULDBLOCK,表示是一个阻塞操作。CAsyncSocket有一个特殊的成员变量m_hSocket,用来保管其对应的Socket句柄。与前面引见的基于WinSock API的编程接口相比,CAsyncSocket类的编程接口除了封装了低层的WinSock API,还添加了很多智能化的设计,最重要的就是对I/O模型(参见6.6.2节)的封装,从而把程序员从复杂的I/O管理中解放出来。CAsy
16、ncSocket类是经过封装了一个CSocketWnd窗口实现这一功能的,封装是在CAsyncSocket的Create()函数中实现的,函数原型如下:2323bool CAsyncSocket:Create( long lEvent ) m_hSocket = socket( PF_INET, SOCK_STREAM, 0 ); /创建Socket本身 CSocketWnd* pSockWnd = new CSocketWnd; /创建呼应事件的CSocketWnd窗口 pSockWnd-Create(); /将Socket事件和窗口用WSAAsyncSelect关联 WSAAsyncSel
17、ect( m_hSocket, pSockWnd-m_hWnd, WM_SOCKET_NOTIFY, lEvent ); 2424可以看出,该函数除了创建了一个SOCKET以外还创建了一个CSocketWnd窗口对象,并运用WSAAsyncSelect()将这个SOCKET与该窗口对象关联,到达让该窗口对象处置来自Socket的事件(音讯)的目的。在MFC框架的支持下,一旦CSocketWnd收到Socket事件后,会回调CAsyncSocket的DoCallBack成员函数,进而调用CAsyncSocket的成员函数OnReceive()、OnSend()、OnAccept()、OnConn
18、ect()等虚函数,进展I/O处置。所以运用CAsyncSocket进展套接字编程时,只需求在它的派生类里的这些虚函数里添加用户本人的发送和接纳代码即可,而无需再进展I/O模型的管理,这大大简化了编程过程。CAsyncSocket:DoCallBack的原型如下:2525static void PASCAL CAsyncSocket:DoCallBack(WPARAM wParam, LPARAM lParam) CAsyncSocket *pSocket; pSocket.Attach( (SOCKET)wParam ); /wParam就是触发这个事件的Socket的句柄 int nErr
19、orCode = WSAGETSELECTERROR(lParam); /lParam是错误码与事件码的合成 switch (WSAGETSELECTEVENT(lParam) 2626 case FD_READ: pSocket-OnReceive(nErrorCode); break; case FD_WRITE: pSocket-OnSend(nErrorCode); break; case FD_OOB: pSocket-OnOutOfBandData(nErrorCode); break; case FD_ACCEPT:2727 pSocket-OnAccept(nErrorCode
20、); break; case FD_CONNECT: pSocket-OnConnect(nErrorCode); break; case FD_CLOSE: pSocket-OnClose(nErrorCode); break; 2828那么CSocketWnd与CAsyncSocket是如何建立联络的呢?是经过CSocketWnd类中定义的音讯与函数的映射实现的。该音讯映射为BEGIN_MESSAGE_MAP(CSocketWnd, CWnd) ON_MESSAGE(WM_SOCKET_NOTIFY, OnSocketNotify) END_MESSAGE_MAP()也就是一旦发生WM_S
21、OCKET_NOTIFY事件(Socket事件),就会调用CSocketWnd:2929OnSocketNotify函数。CSocketWnd:OnSocketNotify函数原型如下: LRESULT CSocketWnd:OnSocketNotify(WPARAM wParam, LPARAM lParam) CAsyncSocket:DoCallBack( wParam, lParam ); /收到Socket事件音讯后,回调CAsyncSocket的DoCallBack()函数 return 0;实践上就是调用了CAsyncSocket:DoCallBack()函数。303010.2.
22、2 类成员类成员下面对下面对CAsyncSocket的类成员函数进展简要的类成员函数进展简要引见,详细定义与运用方法可参看引见,详细定义与运用方法可参看MSDN。1构造函数构造函数CAsyncSocket用来在创建用来在创建CAsyncSocket对象对象时初始化对象,为对象成员变量赋初始值,与时初始化对象,为对象成员变量赋初始值,与new运算符一同运用在创建对象的语句中。运算符一同运用在创建对象的语句中。CAsyncSocke有两个构造函数有两个构造函数CasyncSocket()和和Create(),前者用于构造一个,前者用于构造一个CAsyncSocket对象,对象,后者用于创建一个后者
23、用于创建一个socket。31 312属性函数属性函数为了添加程序设计的灵敏性和可控性,为了添加程序设计的灵敏性和可控性,CAsyncSocket还提供了属性函数和重载函数,大还提供了属性函数和重载函数,大大添加了程序员在编写网络程序时的自在度。大添加了程序员在编写网络程序时的自在度。CAsyncSocket类的属性函数包括类的属性函数包括Attach()、Detach()、FromHandle()、GetLastError()、GetPeerName()、GetSockName()、GetSockOpt()和和SetSockOpt()函数,它们可以获得或改动对象函数,它们可以获得或改动对象的
24、属性,为基于的属性,为基于CAsyncSocket类的网络编程提供类的网络编程提供了网络控制与监测工具。了网络控制与监测工具。32323操作函数操作函数CAsyncSocket操作函数进展网络相关建立的操作函数进展网络相关建立的详细操作,与前面引见的详细操作,与前面引见的WinSock API的对应函的对应函数非常象,实践上就是对这些数非常象,实践上就是对这些API函数的封装。函数的封装。操作函数包括操作函数包括Accept()、Bind()、Close()、Connect()、IOCtl()、Listen()、Receive()、ReceiveFrom()、Send()、SendTo()、S
25、hutDown()。33334重载函数重载函数CAsyncSocket类的重载函数可以向相应程序类的重载函数可以向相应程序通告套接字事件的发生,可以经过重载设计处置通告套接字事件的发生,可以经过重载设计处置相应的网络通讯事件,这些函数都是虚函数。重相应的网络通讯事件,这些函数都是虚函数。重载函数包括载函数包括OnAccept()、OnClose()、OnConnect()、OnOutOfBandData()、OnReceive()、OnSend()。后续的网络处置主要就。后续的网络处置主要就是运用这些函数。是运用这些函数。CAsyncSocket类本身只需一个成员变量,即类本身只需一个成员变量
26、,即m_hSocket,用于指示衔接到,用于指示衔接到CAsyncSocket对象对象的句柄。的句柄。从前面的表达可以看出,从前面的表达可以看出,CAsyncSocket直接直接封装了低层的封装了低层的WinSock API,同时提供了丰富的,同时提供了丰富的成员,简化和丰富了成员,简化和丰富了WinSock编程。编程。343410.2.3 编程步骤编程步骤直接运用直接运用CAsyncSocket进展网络编程的详细进展网络编程的详细运用方法可以概括为以下五个步骤:运用方法可以概括为以下五个步骤:(1) 在堆或者栈中构造一个在堆或者栈中构造一个CAsyncSocket对对象,例如:象,例如:CA
27、syncSocket sock或者或者CAsyncSocket *pSock = new CAsyncSocket;(2) 调用调用Create()创建创建socket,如:运用缺省,如:运用缺省参数创建一个面向衔接的参数创建一个面向衔接的socket,sock.Create() 指定参数创建一个运用数据报的指定参数创建一个运用数据报的socket,本地端,本地端口为口为30,程序代码如下:,程序代码如下:pSocket.Create(30, SOCK_DGRM);3535(3) 假设是客户程序,运用Connect()衔接到远地;假设是效力程序,运用Listen()监听远地的衔接恳求。当收到衔
28、接恳求后,调用Accept()接受该恳求。在接纳衔接恳求后,就可以执行例如确认之类的操作。(4) 运用成员函数进展网络I/O,完成与其他程序的通讯和操作。(5) 销毁CAsyncSocket,析构函数调用,Close()成员函数封锁socket。在MFC网络编程中,通常不直接运用CAsyncSocket类而是会对CAsyncSocket派生出一个新类,并在该类中添加用户本人的一些网络功能(成员)。3636CSocket类是MFC提供的另外一个套接字类,在CAsyncSocket根底上又添加了一些新特性。10.3 MFC CSocket类网络编程类网络编程373710.3.1 CSocket类类
29、CSocket类建立在类建立在CAsyncSocket类的根底上,类的根底上,是是CAsyncSocket类的派生类,派生构造如图类的派生类,派生构造如图10-3所示。所示。CSocket类的对象的用法与类的对象的用法与CAsyncSocket类的对象非常类似,且提供了以下三点改良。类的对象非常类似,且提供了以下三点改良。1成员成员CSocket主要添加或重载了构造函数主要添加或重载了构造函数Csocket()、Create();属性函数;属性函数IsBlocking()、FromHandle()、Attach();操作函数;操作函数CancelBlockingCall();重载函数;重载函数
30、OnMessagePending()。38382同步化同步化CSocket对对CAsyncSocket进展了同步化改造,进展了同步化改造,成为一个典型的同步阻塞成为一个典型的同步阻塞Socket封装类。同步的封装类。同步的方法很简单,以方法很简单,以CSocket的操作函数的操作函数Connect()为为例进展阐明。例进展阐明。CSocket在在Connect()被阻塞时,不被阻塞时,不是在是在OnConnect()、OnReceive()这些事件终端函这些事件终端函数里去等待,而是马上进入一个音讯循环,从当数里去等待,而是马上进入一个音讯循环,从当前线程的音讯队列里取关怀的音讯。假设取到了前
31、线程的音讯队列里取关怀的音讯。假设取到了WM_PAINT音讯,那么刷新窗口;假设取到的是音讯,那么刷新窗口;假设取到的是Socket发来的音讯,那么根据发来的音讯,那么根据Socket能否有操作能否有操作错误码,再调用相应的回调函数错误码,再调用相应的回调函数(OnConnect()等等)。Connect()函数的原型如下:函数的原型如下:3939BOOL CSocket:Connect( . ) if( !CAsyncSocket:Connect( . ) ) if( WSAGetLastError() = WSAEWOULDBLOCK ) /由于被阻塞不能立刻完成,Socket/前往这个错
32、误 /进入音讯循环,从线程音讯队列里查看FD_CONNECT音讯,直到收到该音讯而以为4040/衔接胜利 while( PumpMessages( FD_CONNECT ) ); PumpMessages()函数的原型如下:BOOL CSocket:PumpMessages( UINT uEvent ) CWinThread* pThread = AfxGetThread();41 41 while( bBlocking ) /bBlocking仅仅是一个标志,看用户能否取消对Connect()的调用 MSG msg; if( PeekMessage( &msg, WM_SOCKET_NOTI
33、FY ) ) if( msg.message = WM_SOCKET_NOTIFY & WSAGETSELECTEVENT(msg.lParam) = uStopFlag )4242 CAsyncSocket:DoCallBack( msg.wParam, msg.lParam ); return TRUE; else 4343 OnMessagePending(); /处置音讯队列里的其他音讯 pThread-OnIdle(-1); OnMessagePending实现了前面描画的在阻塞时,从当前线程的音讯队列里取关怀的音讯的功能。BOOL CSocket:OnMessagePending(
34、)4444 MSG msg; if( PeekMessage( &msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE ) ) /这里仅关怀WM_PAINT音讯,以处置阻塞期间的主窗口重画 :DispatchMessage( &msg ); return FALSE; return FALSE;4545其他的CSocket函数,诸如Send()、Receive()、Accept()都会在收到WSAEWOULDBLOCK错误被阻塞时,进入PumpMessages()音讯循环,这样一个本来异步的CAsyncSocket就变成同步的了(实践上CSocket的阻塞不是建立在
35、阻塞的socket根底上,而是在非阻塞socket上实现的阻塞操作),从而更加节省资源、更高效。46463串行化串行化CSocket另一个重要特点就是实现了数据读另一个重要特点就是实现了数据读/写的串行化,提供了可以同写的串行化,提供了可以同CArchive和和CSocketfile这两个类协同任务的接口,三者之间这两个类协同任务的接口,三者之间的关系如图的关系如图10-4所示。其中,所示。其中,CSocketfile类是一类是一种特殊的文件对象,常用它来经过套接字进展数种特殊的文件对象,常用它来经过套接字进展数据的传输,它所提供的接口同普通文件类的接口据的传输,它所提供的接口同普通文件类的接
36、口根本上是一致的。而根本上是一致的。而CArchive类是一个存档类,类是一个存档类,它是将用户的数据保管到永久性存储对象的一种它是将用户的数据保管到永久性存储对象的一种技术。这种复杂的协同任务关系的目的是为了运技术。这种复杂的协同任务关系的目的是为了运用户从套接字细节的管理中脱身出来。用户从套接字细节的管理中脱身出来。4747用户在运用CSocket类时,不用像运用CAsyncSocket类时不得不面对一大堆繁琐的任务,而是像读/写普通文件一样直接进展数据读取就可以了。这样程序员只需求简单地创建套接字、文档和归档,然后经过存储或输入归档以发送或接纳数据。4848图10-4 CSocket、C
37、Archive和CSocketfile三者之间关系4949当然,CSocket类也可以单独运用,不过这样做的话,CSocket的优势就会被大打折扣。下面将在引见CSocketFile和CArchive的根底上,再详细引见基于CSocket类的编程。505010.3.2 CSocketFile类 CSocketFile类承继自CFile类,用于经过WinSock向网络发送和接纳数据。为了深化掌握该类的功能与作用,在引见CSocketFile类之前首先简单引见一下CFile类。Cfile类是微软根底文件类的根本类。它可以直接提供无缓存、二进制文件的输入/输出效力,也可以经过它的基类直接支持对文本文
38、件和内存文件的读写操作。CFile类与其基类的承继关系保证了程序可以经过多态的CFile接口操作一切的文件对象。51 51Cfile类有着一整套的进展磁盘文件操作的成员函数,包括Open()、Close()、Read()、Write()、Seek()、GetPosition()、Duplicate()、GetLength()、Rename()、GetStatus()等,分别可以完成对文件的翻开、封锁、读/写、设定/获得读取指针位置、复制、获取长度、重命名、获取文件形状等操作。Cfile类提供的静态成员函数允许程序员在不翻开文件的情况下了解文件的形状,使得对文件的管理变得非常方便。特别是,CFi
39、le 对象还可以运用 CArchive 类对象进展MFC对象的序列化操作。5252在了解了Cfile类的根本含义和用法后,就不难了解CSocketFile类了。CsocketFile类操作的对象不是文件(或内存内容),而是与CSocket类对象关联的网络I/O,在进展网络编程的时候,可以简单地了解为:引入CSocketFile类的作用实践上就是把网络I/O操作虚拟成为对文件的读写。这就省去了许多数据接纳和发送时的繁琐操作!但是需求留意的是:虽然CsocketFile类承继自CFile类,但是CSocketFile对象不支持CFile的一些成员函数,如Seek()、GetLength()、Set
40、Length()、LockRange()、GetPosition()等函数,调用会出错。5353想要利用上述CSocketFile对象便利地进展网路通讯操作,必需将CSocketFile对象衔接到一个CSocket对象上,执行该类的下面成员函数来实现。CSocketFile( CSocket* pSocket,BOOL bArchiveCompatible = TRUE );参数pSocket为指向关联的CSocket对象指针,参数bArchiveCompatible为能否要使文件对象与归档一同运用(允许不与归档一同运用),缺省值为TURE。5454为了进一步简化基于MFC的串行化编程,还可以
41、把这个衔接Csocket对象的CSocketFile对象再衔接到CArchive对象上。555510.3.3 CArchive类类CArchive类没有基类,它的对象可以对一个类没有基类,它的对象可以对一个缓冲区进展管理。经过提供一个平安缓冲机制,缓冲区进展管理。经过提供一个平安缓冲机制,可以以一个可以以一个CFile对象对象(可以是磁盘文件,也可以可以是磁盘文件,也可以是内存文件是内存文件)为根底,经过为根底,经过“操作符操作符完成对文件的二进制流的操作。完成对文件的二进制流的操作。CArchive可以在可以在对象被删除时,确保数据还能被存储介质永久保对象被删除时,确保数据还能被存储介质永久
42、保管;也可以从永久存储中装载对象,在内存中重管;也可以从永久存储中装载对象,在内存中重新构造它们,这一使数据永久保管的过程就叫作新构造它们,这一使数据永久保管的过程就叫作“串行化。串行化。CArchive对象将数据序列化到存档对象将数据序列化到存档时,存档积累数据,直到其缓冲区被填满为止。时,存档积累数据,直到其缓冲区被填满为止。5656然后,存档将其缓冲区写入 CArchive 对象指向的 CFile 对象。同样,当从存档中读取数据时,存档会将数据从文件读取到它的缓冲区,然后从缓冲区读取到反序列化的对象。这种缓冲减少了物理读取硬盘的次数,从而提高了运用程序的性能。更重要的是,CArchive
43、类对象允许以一个永久二进制(通常为磁盘存储)的方式保管一个对象的复杂网络,这一点对WinSock网络编程非常有用。根据CArchive对象可以对一个缓冲区进展管理的特点,再加上上述CSocketFile是一种特殊的Cfile,其对象完全可以被CArchive对象所管理,同时思索到CSocket可以提供阻塞操作,因此经过三者配合完全可以像读/写文件一样读/写Socket数据。5757将CArchive对象衔接到一个CSocketFile对象上,可经过执行该类的构造函数操作实现。m_arIn=new CArchive(m_file, CArchive:load); /建立数据流入的CArchive
44、对象与CSocketFile对象关联m_arOut=new CArchive(m_file, CArchive:store); /建立数据流出的CArchive对象与CSocketFile对象关联这里,m_arIn、m_arOut为CArchive对象,m_file是CSocketFile对象。5858CArchive类拥有众多的成员函数,如Carchive()、Read()、Write()、SetStoreParams()、SetObjectSchema()分别完成对象的构造、数据的读/写、参数的设定等功能,但在网络编程中最常用的是“操作和Flush函数,分别完成对数据的写和读。二者都可进展
45、多种数据的操作,假设出现异常,将控制权交给异常处置程序处置。Flush()函数的原型为void Flush( );throw(CFileException);5959该函数用于确定能否一切的数据曾经从CArchive对象传入文件中,假设出现异常,将控制权交给异常处置程序处置。另外,CArchive类还有一个非常重要的成员函数IsBufferEmpty()。当CSocketFile()独立运用时,由于数据是分多个音讯多次送达的,所以进展Read操作时能够出现无限等待。能够出现的问题是:没有读取到指定长度的数据并不表示数据读取终了,从而导致程序阻塞。对于这种情况,可以让CSocketFile和CA
46、rchive配合运用,但仅仅读取到数据就前往。至于数据能否读取终了,就需求运用CArchive的IsBufferEmpty()函数来判别能否缓存里存在数据,只需存在数据就可以进展读操作了。IsBufferEmpty()函数的原型为6060BOOL IsBufferEmpty( ) const;假设数据为空,函数前往非0值,否那么为0。在利用CArchive类对象编程时该当留意,给定的 CArchive 对象要么存储数据(即写入数据或将数据序列化),要么加载数据(即读取数据或将数据反序列化),但决不能同时进展。CArchive 对象的寿命只限于将对象写入文件或从文件读取对象的一次传送。因此,需求
47、在一个相关上进展双工通讯,就需求两个延续创建的CArchive 对象,分别用于将数据序列化到文件和从文件反序列化数据。61 6110.3.4 编程步骤编程步骤CSocket类提供了比类提供了比CAsyncSocket类更高级类更高级的笼统,它承继了的笼统,它承继了CAsyncSocket类的许多封装了类的许多封装了Windows插口插口API的成员函数,而且管理了通讯的成员函数,而且管理了通讯的大多数方面,包括大部分本应运用原始的大多数方面,包括大部分本应运用原始API或或者者CAsyncSocket类进展处置的任务,因此运用更类进展处置的任务,因此运用更加容易。除了上面提到的它运用加容易。除
48、了上面提到的它运用MFC序列化协议序列化协议完成套接字数据处置,与完成套接字数据处置,与CAsyncSocket类不同,类不同,CSocket类的网络类的网络I/O可以设定为是阻塞的可以设定为是阻塞的(缺省情缺省情况下是非阻塞况下是非阻塞),即它在完成义务之后才前往。这,即它在完成义务之后才前往。这在网络编程中是极其有用的。在网络编程中是极其有用的。6262利用CSocket类进展编程,要重点了解它的阻塞特点,以及CSocket类、CArchive类和CSocketfile类之间的关系,在编程过程中尤其要留意上述三个类对象的运用顺序。运用CSocket进展网络编程的详细运用方法可以概括为以下八
49、个步骤。(1) 构造效力器和效力器套接字对象;(2) 调用Create()函数创建套接字;(3) 套接字创建终了后,效力器调用Listen()函数开场监听客户机的衔接恳求,而客户机可以调用Connetct()函数向效力器发出衔接恳求;6363(4) 当效力器监听到客户机有衔接恳求时,创建一个新的套接字,再调用Accept()成员函数以接纳客户机的衔接恳求;(5) 效力器和客户机的套接字对象分别创建一个与其联络的CSocketFile对象;(6) 效力器和客户机的套接字对象分别创建两个与CSocketfile相关联的CArchive对象,以便进展数据的发送和接纳;(7) 运用CArchive对象
50、在客户机和效力器套接字之间传送数据;6464(8) 义务完成后,销毁CArchive、CSocketFile和CSocket对象。由于CArchive对象只能单向传送数据,因此在实践运用中必需定义两个CArchive对象,一个用于发送,另一个用于数据的接纳。在以上任务步骤中,第(1)(4)步与CAsyncSocket类的编程步骤完全一样,需求重点区别的在于第(5)(8)步。6565为了演示MFC套接字的编程,本节引见一个多媒体网络通讯编程的实现。10.4 多媒体通讯编程多媒体通讯编程666610.4.1 多媒体网络传输技术多媒体网络传输技术在网络上传输音在网络上传输音/视频数据除了网络本身的传
51、视频数据除了网络本身的传输数据以外,还需求运用紧缩编码技术,紧缩编输数据以外,还需求运用紧缩编码技术,紧缩编码技术可以说是计算机处置、传输音码技术可以说是计算机处置、传输音/视频数据的视频数据的前提。通常,视频信号数字化后数据带宽很高,前提。通常,视频信号数字化后数据带宽很高,达达20Mb/s以上,因此计算机很难对其进展保管处以上,因此计算机很难对其进展保管处置、网络传输。原始的单个音频数据虽然有时不置、网络传输。原始的单个音频数据虽然有时不是很大,但是由于音频数据运用非常频繁,往往是很大,但是由于音频数据运用非常频繁,往往是多路、并发的,因此不进展任何紧缩处置,也是多路、并发的,因此不进展任
52、何紧缩处置,也不适宜直接在网络上进展传输。采用紧缩编码技不适宜直接在网络上进展传输。采用紧缩编码技术以后通常可以使视频数据带宽降到术以后通常可以使视频数据带宽降到110Mb/s,音频数据的紧缩效率更高,这样就可以将音音频数据的紧缩效率更高,这样就可以将音/视频视频信号在网络上传输了。信号在网络上传输了。67671紧缩编码规范紧缩编码规范传统的紧缩编码是建立在香农传统的紧缩编码是建立在香农(Shannon)信息信息论根底上的。香农信息论以经典的集合论为根底,论根底上的。香农信息论以经典的集合论为根底,用统计概率模型来描画信源,从中可以发现,描用统计概率模型来描画信源,从中可以发现,描画信源的数据
53、量总是大于信源本身这一现实,可画信源的数据量总是大于信源本身这一现实,可以推断数据冗余客观存在。因此,经过去除数据以推断数据冗余客观存在。因此,经过去除数据的冗余信息就可以到达紧缩的目的。紧缩技术的的冗余信息就可以到达紧缩的目的。紧缩技术的目的就是尽能够多地将数据中的冗余信息去掉目的就是尽能够多地将数据中的冗余信息去掉(去去除数据之间的相关性除数据之间的相关性)。紧缩编码的开展历程实践。紧缩编码的开展历程实践上是以香农信息论为出发点,一个不断完善的过上是以香农信息论为出发点,一个不断完善的过程。程。6868由于多媒体数据有极强的相关性,也就是说有大量的冗余信息,因此非常适宜紧缩编码技术的运用。
54、视频中的冗余信息可分为空域冗余信息和时域冗余信息,针对这些冗余信息的特征可以采用帧内图像数据紧缩技术、帧间图像数据紧缩技术和熵编码紧缩技术。数字音频信息存在音频信息本身的相关性以及人耳对音频信息的听觉冗余度,因此可以采用波形编码、参数编码以及混合编码等三类技术。目前,很多适用、有效的音/视频紧缩编码规范曾经被广泛的运用到各个领域,常见的有:69691) MPEG系列由ISO国际规范组织机构下属的MPEG(运动图像专家组)开发,视频编码方面主要是MPEG-1(VCD)、MPEG-2(DVD)、MPEG-4(如DIVX、XVID等)、MPEG-4 AVC;音频编码方面主要是MPEG Audio L
55、ayer 1/2、MPEG Audio Layer 3(MP3)、MPEG-2 AAC、MPEG-4 AAC等。2) H.26X系列由ITU国际电视讯联盟主导,偏注重频数据的网络传输,包括H.261、H.262、H.263、H.263+、H.263+、H.264等。70703) 其他结合视频任务组(JVT,Joint Video Team)的新一代数字视频紧缩规范;监控行业中分辨率规范有SQCIF、QCIF、CIF、4CIF,等等。71 712流媒体技术流媒体技术所谓流媒体,是指采用流式传输的方式在所谓流媒体,是指采用流式传输的方式在Internet播放的媒体格式。流媒体又叫流式媒体,播放的媒
56、体格式。流媒体又叫流式媒体,它是指视频提供者用一个视频传送效力器把节目它是指视频提供者用一个视频传送效力器把节目当成数据包发出,传送到网络上。用户经过解压当成数据包发出,传送到网络上。用户经过解压设备对这些数据进展解压后,视频就会像发送前设备对这些数据进展解压后,视频就会像发送前那样显示出来。与这个过程的一系列相关的包称那样显示出来。与这个过程的一系列相关的包称为为“流。流媒体实践指的是一种新的媒体传送流。流媒体实践指的是一种新的媒体传送方式,而非一种新的媒体。方式,而非一种新的媒体。7272流式传输的实现需求缓存。由于Internet以包传输为根底进展断续的异步传输,对一个实时A/V源或存储
57、的A/V文件,在传输中它们要被分解为许多包,由于网络是动态变化的,各个包选择的路由能够不尽一样,故到达客户端的时间延迟也就不等,甚至先发的数据包还有能够后到。为此,可以运用缓存系统来弥补延迟和抖动的影响,并保证数据包的顺序正确,从而使媒体数据能延续输出,而不会由于网络暂时拥塞而使播放出现停顿。7373通常高速缓存所需容量并不大,由于高速缓存运用环形链表构造来存储数据:经过丢弃曾经播放的内容,流可以重新利用空出的高速缓存空间来缓存后续尚未播放的内容。流式传输的实现需求适宜的传输协议。由于TCP需求较多的开销,故不太适宜传输实时数据。在流式传输的实现方案中,普通采用HTTP/TCP来传输控制信息,
58、而用RTP/UDP来传输实时声音数据。流式传输的过程普通是这样的:用户选择某一流媒体效力后,Web阅读器与Web效力器之间运用HTTP/TCP交换控制信息,7474以便把需求传输的实时数据从原始信息中检流媒体制造检索出来;然后客户机上的Web阅读器启动A/V Helper程序,用HTTP从Web效力器检索相关参数并对Helper程序进展初始化。这些参数能够包括目录信息、A/V数据的编码类型或与A/V检索相关的效力器地址7575流媒体实现需求三部分软/硬件产品,详细如下:(1) 编码器:它由计算机、视频采集卡和流媒体编码软件组成。流媒体采集卡担任将音/视频信息源输入计算机,供编码软件处置;编码软
59、件担任将流媒体采集卡传送过来的数字音/视频信号紧缩成流媒体格式。假设做直播,它还担任实时地将紧缩好的流媒体信号上传给流媒体效力器。(2) 效力器:由流媒体软件系统效力器和一台硬件效力器组成。这部分担任管理、存储、分发编码器传上来的流媒体节目。7676(3) 终端播放器(解码器):这部分由流媒体系统的播放软件和一台普通PC组成,用来播放用户想要收看的流媒体效力器上的视频节目。77773DirectShowDirectShow是微软公司在是微软公司在ActiveMovie和和Video for Windows的根底上推出的新一代基于的根底上推出的新一代基于COM(Component Object
60、Model)的流媒体处置的的流媒体处置的开发包,与开发包,与DirectX开发包一同发布。目前,开发包一同发布。目前,DirectX的最新版本为的最新版本为11。DirectShow为多媒体流为多媒体流的捕捉和回放提供了强有力的支持。运用的捕捉和回放提供了强有力的支持。运用DirectShow,可以很方便地从支持,可以很方便地从支持WDM驱动模驱动模型的采集卡上捕获数据,并且进展相应的后期处型的采集卡上捕获数据,并且进展相应的后期处置甚至存储到文件中。这样使在多媒体数据库管置甚至存储到文件中。这样使在多媒体数据库管理系统理系统(MDBMS)中多媒体数据的存取变得更加中多媒体数据的存取变得更加方
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 广东科贸职业学院《综合英语一》2023-2024学年第一学期期末试卷
- 广东交通职业技术学院《苗木繁育技术实践》2023-2024学年第一学期期末试卷
- 广东技术师范大学《小学数学教学案例研究》2023-2024学年第一学期期末试卷
- 广东工商职业技术大学《双创竞赛训练营》2023-2024学年第一学期期末试卷
- 广东第二师范学院《新媒体创新与创业》2023-2024学年第一学期期末试卷
- 广东潮州卫生健康职业学院《数据库技术MySQ》2023-2024学年第一学期期末试卷
- 模板支撑培训课件
- 蛋糕生产工艺培训课件
- 《汽车空调工作原理》课件
- 《神经内科急症》课件
- 小流域水土保持综合治理工程初步设计
- 增强热塑性塑料复合管在我国的发展现状
- 机械设计外文文献翻译、中英文翻译、外文翻译
- 美标渐开线花键计算程序2014.8
- 英格索兰空压机操作规程
- 简单通用利润表
- 风动送样手册
- 绩效考核评分标准
- 电力建设施工技术管理
- NB∕T 32004-2018 光伏并网逆变器技术规范
- (完整word版)儿童感觉统合能力发展评定量表
评论
0/150
提交评论