《第6章高级网络编程.ppt》由会员分享,可在线阅读,更多相关《第6章高级网络编程.ppt(25页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Windows网络程序设计网络程序设计第第6章章 高级网络编程高级网络编程6.1 MFC概述概述nMFC(Microsoft foundation Classes)是微是微软公司提供的用于软公司提供的用于C+程序设计的基础类库程序设计的基础类库,它由两部分组成它由两部分组成:一部分是通常所说的一部分是通常所说的C+类训类训,是是MFC类库的主体部分类库的主体部分;另一部分是另一部分是MFC预定义宏、全局变量和全局函数,是预定义宏、全局变量和全局函数,是MFC类库的辅助部分。类库的辅助部分。nMFC类库中定义的类主要有以下几种:类库中定义的类主要有以下几种:(1)根类()根类(CObject):
2、):CObject实现了一些实现了一些重要的特性,包括动态类信息、动态创建、对重要的特性,包括动态类信息、动态创建、对象序列化、对程序调试的支持等等。象序列化、对程序调试的支持等等。(2)命令发送类()命令发送类(CCmdTarget):):CCmdTarget通过封装了用户通过菜单或工具通过封装了用户通过菜单或工具栏向应用程序发送命令的界面,提供了消息处栏向应用程序发送命令的界面,提供了消息处理的架构。它是应用程序结构类和窗口类的基理的架构。它是应用程序结构类和窗口类的基类。类。(3)应用程序结构类。提供了应用程序的所有通用功)应用程序结构类。提供了应用程序的所有通用功能,它们构成了能,它们
3、构成了windows应用程序的主要框架。应用应用程序的主要框架。应用程序类主要有以下几种:程序类主要有以下几种:n应用程序线程支持类:应用程序线程支持类:CWinThread类是所有线程类的基类,类是所有线程类的基类,封装了操作应用程序的多线程功能。封装了操作应用程序的多线程功能。CWinApp是是CWinThread的派生类,它封装了基于的派生类,它封装了基于MFC的的Windows应用应用程序的初始化、运行及终止等功能。程序的初始化、运行及终止等功能。CWinApp的全局对象控的全局对象控制着整个应用程序的流程。制着整个应用程序的流程。n文档类。文档类封装了应用程序的数据管理,文档类对象由
4、文文档类。文档类封装了应用程序的数据管理,文档类对象由文档模板创建。档模板创建。CDocument类是文档类的基类,它支持一些标类是文档类的基类,它支持一些标准的操作,如新建文档,打开文档和存储文档等。准的操作,如新建文档,打开文档和存储文档等。n文档模板类。文档模板类将文档、视图及边框窗口相互联系起文档模板类。文档模板类将文档、视图及边框窗口相互联系起来,在创建新文档或视图时协调文档、视图及边框窗口的创建。来,在创建新文档或视图时协调文档、视图及边框窗口的创建。CMultiDoctemplate为多文档接口提供了模板。为多文档接口提供了模板。CSingleDocTemplate为单文档接口提
5、供了模板。为单文档接口提供了模板。(4)窗口类。包括边框窗口类、视图类、对)窗口类。包括边框窗口类、视图类、对话框类、控件类、控件栏类和属簿类,它们的话框类、控件类、控件栏类和属簿类,它们的共同之处是都封装了一个窗口句柄共同之处是都封装了一个窗口句柄HWND,都,都是从是从CWnd派生的。派生的。(5)常用工具类,如用于绘图的类、数组类)常用工具类,如用于绘图的类、数组类等。等。(6)非派生自)非派生自CObject的类,如用于的类,如用于Internet服务程序设计的服务程序设计的API。nMFC对编程的强大支持功能是通过以下几点实现的:对编程的强大支持功能是通过以下几点实现的:(1)MFC
6、封装了封装了Win32 API、OLE API、ODBC API等底层函数等底层函数的功能,并提供更高一层的接口,简化了的功能,并提供更高一层的接口,简化了Windows编程。同时,编程。同时,MFC支持对底层支持对底层API的直接调用。的直接调用。(2)MFC提供了一个提供了一个Windows应用程序开发模式,对程序的控制应用程序开发模式,对程序的控制主要是由主要是由MFC框架完成的,而且框架完成的,而且MFC也完成了大部分的功能,预也完成了大部分的功能,预定义或实现了许多事件和消息处理等。框架或者由其本身处理事定义或实现了许多事件和消息处理等。框架或者由其本身处理事件而不依赖程序员的代码,
7、或者调用程序员的代码来处理应用程件而不依赖程序员的代码,或者调用程序员的代码来处理应用程序特定的事件。序特定的事件。(3)MFC是是C+类库,程序员就是通过使用、继承和扩展适当的类库,程序员就是通过使用、继承和扩展适当的类来实现特定的目的的。实现这种功能的基础是类来实现特定的目的的。实现这种功能的基础是C+对继承的支对继承的支持,对虚拟函数的支持,以及持,对虚拟函数的支持,以及MFC实现的消息映射机制。实现的消息映射机制。nMFC中与网络程序设计有关的类有:中与网络程序设计有关的类有:(1)文件服务类:)文件服务类:nCSocketFile,派生自,派生自CFile类,用于将需要序列化的数据如
8、类,用于将需要序列化的数据如一些结构体数据、对象等传给对方。一些结构体数据、对象等传给对方。(2)Internet服务器服务器API类类n与与HTTP有关的类,有关的类,CHemlStream、CHttpFilter、CHttpFilterContext、CHttpServer和和CHttpServerContext。(3)Internet服务类服务类n与与Internet会话有关的会话有关的CInternetSession,与,与Internet连接有连接有关的关的CinternetConnection(CFtpconnection、CGopherconnection、CHttpConnec
9、tion),与查找文件有),与查找文件有关的关的CFileFind(CFtpFilefind,CGopherFilefind)(4)Windows套接口类套接口类nMFC中定义了一个中定义了一个Windows套接口程序设计类套接口程序设计类CAsyncsocket,还定义了一个派生于,还定义了一个派生于CAsyncsocket的的CSocket类。类。6.2 MFC Socket类网络编程类网络编程n6.2.1 CAsyncSocket类类 CAsyncSocket类派生自类派生自CObject类,利用它可以方便类,利用它可以方便地处理有关网络行为的通知消息。地处理有关网络行为的通知消息。CA
10、syncSocket封封装了低层的装了低层的WinSock API,它在原有的,它在原有的WinSock函数函数的基础上提供了一些面向对象的特性,如连接、接收的基础上提供了一些面向对象的特性,如连接、接收事件。事件。CAsyncSocket类所提供的唯一的抽象就是将类所提供的唯一的抽象就是将与套接字相联系的与套接字相联系的Windows消息以回调函数的形式表消息以回调函数的形式表示。示。CAsyncSocket类是用于异步类是用于异步WinSock调用的一调用的一个包容类。个包容类。缺省情况下,使用该类创建的缺省情况下,使用该类创建的Socket是非阻塞的是非阻塞的Socket,所有操作都会立
11、即返回,如果没有得到结果,所有操作都会立即返回,如果没有得到结果,返回返回WSAEWOULDBLOCK,表示是一个阻塞操作。,表示是一个阻塞操作。CAsyncSocket有一个特殊的成员变量有一个特殊的成员变量m_hSocket,用来保存其对应的用来保存其对应的SOCKET句柄。句柄。CAsyncSocket的编程步骤如下:的编程步骤如下:n(1)在堆或者栈中构造一个在堆或者栈中构造一个CAsyncSocket对象。对象。n(2)调用调用Create创建创建Socket。n(3)如果是客户程序,使用如果是客户程序,使用Connect连接到远地;连接到远地;如果是服务程序,使用如果是服务程序,使
12、用Listen监听远地的连接请求。监听远地的连接请求。当收到连接请求后,调用当收到连接请求后,调用Accept接受该请求。在接接受该请求。在接收连接请求后,就可以执行如确认之类的操作了。收连接请求后,就可以执行如确认之类的操作了。n(4)使用成员函数进行网络使用成员函数进行网络I/O,完成与其他程序的,完成与其他程序的通信。通信。n(5)调用调用Close成员函数关闭成员函数关闭Socket,销毁,销毁CasyncSocket。n6.2.2 CSocket类类 CSocket类建立在类建立在CAsyncSocket类的基础上,是类的基础上,是CAsyncSocket类的派生类。注意,缺省情况下
13、使用该类创建的类的派生类。注意,缺省情况下使用该类创建的Socket是非阻塞的是非阻塞的Socket。CSocket类有一个重要特点就是提供了可以同类有一个重要特点就是提供了可以同CArchive和和CSocketFile这两个类协同工作的接口这两个类协同工作的接口1.CSocketFile类类 nCSocketfile类继承自类继承自CFile类,用于通过类,用于通过Winsock向网络发送向网络发送和接收数据。和接收数据。nCFile是微软基础文件类的基本类。它可以直接提供无缓存、是微软基础文件类的基本类。它可以直接提供无缓存、二进制文件的输入二进制文件的输入/输出服务,也可以通过它的基类
14、直接支持输出服务,也可以通过它的基类直接支持对文本文件和内存文件的读对文本文件和内存文件的读/写操作。写操作。CFile类与其基类的继承类与其基类的继承关系保障了程序能够通过多态的关系保障了程序能够通过多态的CFile接口操作所有的文件对接口操作所有的文件对象。此外,象。此外,CFile对象还可以使用对象还可以使用CArchive类对象进行类对象进行MFC对对象的序列化操作。象的序列化操作。nCSocketFile类与类与CFile类的重要区别在于,类的重要区别在于,CSocketFile操作操作的对象不是文件的对象不是文件(或内存内容或内存内容),而是与,而是与CSocket类对象关联的类对
15、象关联的网络网络I/O。CSocketFile有有“兼容归档兼容归档”和和“不兼容归档不兼容归档”两种两种工作模式,可供用户选择使用。工作模式,可供用户选择使用。2.CArchive类类nCArchive类没有基类,它的对象能够对一个缓冲区进行管理。类没有基类,它的对象能够对一个缓冲区进行管理。通过提供一个安全缓冲机制,可以以一个通过提供一个安全缓冲机制,可以以一个CFile对象为基础,对象为基础,通过通过“”操作符完成对文件的二进制流的操作。操作符完成对文件的二进制流的操作。nCArchive可以在对象被删除时还能永久保存;也可以从永久可以在对象被删除时还能永久保存;也可以从永久存储中装载对
16、象,在内存中重新构造它们,这一使数据永久保存储中装载对象,在内存中重新构造它们,这一使数据永久保留的过程就叫作留的过程就叫作“串行化串行化”。nCArchive类对象允许以一个永久二进制类对象允许以一个永久二进制(通常为磁盘存储通常为磁盘存储)的的形式保存一个对象的复杂网络,这一点对形式保存一个对象的复杂网络,这一点对Windows Sockets网络编程非常有用。根据网络编程非常有用。根据CArchive对象能够对一个缓冲区进对象能够对一个缓冲区进行管理的特点,再加上上述行管理的特点,再加上上述CSocketFile是一种特殊的是一种特殊的CFile,且其对象完全能够被且其对象完全能够被CA
17、rchive对象所管理,同时考虑到对象所管理,同时考虑到CSocket可以提供阻塞操作,因而通过这三者的配合完全可以可以提供阻塞操作,因而通过这三者的配合完全可以像读像读/写文件一样读写文件一样读/写写Socket网络网络I/O数据。数据。3.CSocket类类nCSocket类提供了比类提供了比CAsyncSocket类更高级的抽象,它继承类更高级的抽象,它继承了了CAsyncSocket类的许多封装了类的许多封装了Windows插口插口API的成员函的成员函数,而且管理了通信的大多数方面,包括大部分本应使用原始数,而且管理了通信的大多数方面,包括大部分本应使用原始API或者或者CAsync
18、Socket类进行处理的工作,因而使用更加容类进行处理的工作,因而使用更加容易。除了上面提到的它使用易。除了上面提到的它使用MFC序列化协议完成套接字数据处序列化协议完成套接字数据处理与理与CAsyncSocket类不同,类不同,CSocket类的网络类的网络I/O还可以设还可以设定为阻塞定为阻塞(缺省情况下是非阻塞缺省情况下是非阻塞),即它在完成任务之后才返回,即它在完成任务之后才返回,这在网络编程中是极其有用的。这在网络编程中是极其有用的。nCSocket对象的阻塞不是建立在阻塞的对象的阻塞不是建立在阻塞的Socket基础上,而是基础上,而是在非阻塞在非阻塞Socket上实现的阻塞操作。在
19、阻塞期间,上实现的阻塞操作。在阻塞期间,CSocket对象使用了一个消息循环,因此虽然是阻塞操作,但是并不影对象使用了一个消息循环,因此虽然是阻塞操作,但是并不影响消息循环,即用户仍然可以和程序交互。响消息循环,即用户仍然可以和程序交互。4.CSocket类的编程步骤类的编程步骤n(1)构造服务器和客户机套接字对象。构造服务器和客户机套接字对象。n(2)调用调用Create函数创建套接字。函数创建套接字。n(3)套接字创建完毕后,服务器调用套接字创建完毕后,服务器调用Listen函数开始侦听客户机的连函数开始侦听客户机的连接请求,而客户机可以调用接请求,而客户机可以调用Connect函数向服务
20、器发出连接请求。函数向服务器发出连接请求。n(4)当服务器监听到客户机有连接请求时,创建一个新的套接字,再当服务器监听到客户机有连接请求时,创建一个新的套接字,再调用调用Accept成员函数以接受客户机的连接请求。成员函数以接受客户机的连接请求。n(5)服务器和客户机的套接字对象分别创建一个与其联系的服务器和客户机的套接字对象分别创建一个与其联系的CSocketFile对象。对象。n(6)服务器和客户机的套接字对象分别创建两个与服务器和客户机的套接字对象分别创建两个与CSocketFile相关相关联的联的CArchive对象,以便进行数据的发送和接收。对象,以便进行数据的发送和接收。n(7)用
21、户通过操作用户通过操作CArchive对象在客户机和服务器套接字之间传送数对象在客户机和服务器套接字之间传送数据。据。n(8)任务完成后,销毁任务完成后,销毁CArchive、CSocketFile和和CSocket对象。由对象。由于于CArchive对象只能单向传递数据,所以在实际使用中必须定义两对象只能单向传递数据,所以在实际使用中必须定义两个个CArchive对象,一个用于发送,另一个用于数据的接收。对象,一个用于发送,另一个用于数据的接收。6.3 多线程多线程WinSock网络编程网络编程 n6.3.1 多线程概论多线程概论 1.进程与线程的定义进程与线程的定义n进程是指一个可执行程序
22、的实例,进程包括运行中的程序和程进程是指一个可执行程序的实例,进程包括运行中的程序和程序所使用到的内存和系统资源。序所使用到的内存和系统资源。n线程是指进程的一条执行路径,是操作系统分时调度分配线程是指进程的一条执行路径,是操作系统分时调度分配CPU时间的基本实体。一个线程可执行程序的任意部分的代码,即时间的基本实体。一个线程可执行程序的任意部分的代码,即使这部分代码被另一个线程并发地执行;一个进程的所有线程使这部分代码被另一个线程并发地执行;一个进程的所有线程可共享它的虚拟地址空间、全局变量和操作系统资源。可共享它的虚拟地址空间、全局变量和操作系统资源。2.进程与线程的关系进程与线程的关系n
23、一个应用程序可以有一个或多个进程,一个进程又是由多个线一个应用程序可以有一个或多个进程,一个进程又是由多个线程所组成的。程所组成的。n线程作为进程中的一个执行流,每个线程都有自己的专有寄存线程作为进程中的一个执行流,每个线程都有自己的专有寄存器器(栈指针、程序计数器等栈指针、程序计数器等),但代码区是共享进程所拥有的,但代码区是共享进程所拥有的,即不同的线程可以执行同一进程内同样的函数。即不同的线程可以执行同一进程内同样的函数。n一个进程中的众多线程中,有一个是主线程。一个进程中的众多线程中,有一个是主线程。3.多线程网络编程原理多线程网络编程原理n多线程程序设计能够适合以下几种编程环境:多线
24、程程序设计能够适合以下几种编程环境:n*通过网络通过网络(例如,与例如,与 Web 服务器、数据库或远程服务器、数据库或远程对象对象)进行通信;进行通信;n*执行需要较长时间因而可能导致执行需要较长时间因而可能导致 UI 冻结的本地操冻结的本地操作;作;n*区分各种优先级的任务;区分各种优先级的任务;n*提高应用程序启动和初始化的性能。提高应用程序启动和初始化的性能。图6.4 多线程网络编程原理 n6.3.2 基本线程操作函数基本线程操作函数1.创建线程函数创建线程函数nHANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,D
25、WORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);2.设置线程的优先级函数设置线程的优先级函数nBOOL SetThreadPriority(HANDLE hThread,int nPriority);3.等待函数等待函数n1)等待单个对象等待单个对象:SignalObjectAndWait、WaitForSingleObject、WaitForSingleObjectEx等等n2)等待多个对象等待多个对象:Wai
26、tForMultipleObjects、WaitForMultipleObjectsEx、MsgWaitForMultiple-Objects、MsgWaitForMultipleObjectsEx等等n3)可以发出提示的等待函数可以发出提示的等待函数:MsgWaitForMultipleObjectsEx、SignalObjectAndWait、WaitForMultiple-ObjectsEx、WaitForSingleObjectEx等,这些函数主要用于重叠等,这些函数主要用于重叠(Overlapped)的的I/O(异步异步I/O)。4.终止一个线程函数终止一个线程函数nVOID Exi
27、tThread(DWORD dwExitCode);nVOID ExitThread(DWORD dwExitCode);n6.3.3 线程同步线程同步在进行多线程工作过程中,线程之间有可能引起冲突。同步可以在进行多线程工作过程中,线程之间有可能引起冲突。同步可以保证在一个时间内只有一个线程对某个共享资源保证在一个时间内只有一个线程对某个共享资源(如操作系统资源如操作系统资源等共享资源,包括全局变量、公共数据成员或者句柄等等共享资源,包括全局变量、公共数据成员或者句柄等)有控制权。有控制权。同步还可以使得有关联交互作用的代码按一定的顺序执行。同步还可以使得有关联交互作用的代码按一定的顺序执行。
28、线程的同步可分用户模式的线程同步和内核对象的线程同步两大线程的同步可分用户模式的线程同步和内核对象的线程同步两大类。类。用户模式中线程的同步方法主要有原子访问和临界区等方法。其用户模式中线程的同步方法主要有原子访问和临界区等方法。其特点是同步速度特别快,适合于对线程运行速度有严格要求的场特点是同步速度特别快,适合于对线程运行速度有严格要求的场合。合。内核对象的线程同步则主要由事件、等待定时器、信号量以及信内核对象的线程同步则主要由事件、等待定时器、信号量以及信号灯等内核对象构成。内核对象同步机制同步速度较慢,但在适号灯等内核对象构成。内核对象同步机制同步速度较慢,但在适用性上却要远优于用户模式
29、的线程同步方式。用性上却要远优于用户模式的线程同步方式。网络编程中具体可使用的同步对象主要有临界区网络编程中具体可使用的同步对象主要有临界区(Critical_section)、事件、事件(Event)、互斥、互斥(Mutex)和信号量和信号量(Semaphores)等。等。1.临界区临界区n临界区是一段独占对某些共享资源访问的代码,在临界区是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问。如任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将
30、被线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。到用原子方式操作共享资源的目的。n以临界区对象来保持线程同步用到的函数主要有以临界区对象来保持线程同步用到的函数主要有InitializeCriticalSection、EnterCriticalSection、LeaveCriticalSection。2.事件事件n事件对象对线程的控制是通过对事件对象的位状态控制来实现的。如事件对象对线程的控
31、制是通过对事件对象的位状态控制来实现的。如果事件为置位状态,则线程可以对共享资源进行操作;如果为复位状果事件为置位状态,则线程可以对共享资源进行操作;如果为复位状态则不能。态则不能。n常用的保持线程同步用到的函数主要有常用的保持线程同步用到的函数主要有CreateEvent、OpenEvent、SetEvent、ResetEvent、PulseEvent等等3.互斥互斥n互斥是一种用途非常广泛的内核对象,能够保证多个线程对同一共享互斥是一种用途非常广泛的内核对象,能够保证多个线程对同一共享资源的互斥访问。资源的互斥访问。n以互斥对象来保持线程同步用到的函数主要有以互斥对象来保持线程同步用到的函数主要有CreateMutex、OpenMutex、ReleaseMutex等等4.信号量信号量n信号量是一个可以用来控制多个进程存取共享资源的计数器。信号量是一个可以用来控制多个进程存取共享资源的计数器。n以信号量对象来保持线程同步用到的函数主要有以信号量对象来保持线程同步用到的函数主要有CreateSemaphore、OpenSemaphore和和ReleaseSemaphore等。等。n6.3.4 多线程网络程序设计多线程网络程序设计例例:局域网内的多线程文件传送局域网内的多线程文件传送