梅芳-网络编程-复习.ppt

上传人:小飞机 文档编号:6052155 上传时间:2023-09-18 格式:PPT 页数:89 大小:540KB
返回 下载 相关 举报
梅芳-网络编程-复习.ppt_第1页
第1页 / 共89页
梅芳-网络编程-复习.ppt_第2页
第2页 / 共89页
梅芳-网络编程-复习.ppt_第3页
第3页 / 共89页
梅芳-网络编程-复习.ppt_第4页
第4页 / 共89页
梅芳-网络编程-复习.ppt_第5页
第5页 / 共89页
点击查看更多>>
资源描述

《梅芳-网络编程-复习.ppt》由会员分享,可在线阅读,更多相关《梅芳-网络编程-复习.ppt(89页珍藏版)》请在三一办公上搜索。

1、网络编程,主讲:王新颖wxyal,吉林大学软件学院,1.1 网络编程相关的基本概念,1.1.1 网络编程与进程通信1进程与线程的基本概念 进程是处于运行过程中的程序实例,是操作系统调度和分配资源的基本单位。一个进程实体由程序代码、数据和进程控制块三部分构成。各种计算机应用程序在运行时,都以进程的形式存在。网络应用程序也不例外。,第一页 最后一页,吉林大学软件学院,Windows系统不但支持多进程,还支持多线程。当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创建其他的线程,而这些线程又能创建更多的线程。Windows 2000能够在拥有多个CPU的计算机上运行,每个

2、CPU上运行不同的线程,达到多线程运行。,Windows系统,第一页 最后一页,吉林大学软件学院,2网络应用进程在网络体系结构中的位置 从计算机网络体系结构的角度来看,网络应用进程处于网络层次结构的最上层。从功能上,可以将网络应用程序分为两部分,一部分是专门负责网络通信的模块,它们与网络协议栈相连接,借助网络协议栈提供的服务完成网络上数据信息的交换。另一部分是面向用户或者作其他处理的模块,它们接收用户的命令,或者对借助网络传输过来的数据进行加工,这两部分模块相互配合,来实现网络应用程序的功能。,第一页 最后一页,吉林大学软件学院,网络应用程序最终要实现网络资源的共享,共享的基础就是必须能够通过

3、网络轻松地传递各种信息。网络编程首先要解决网间进程通信的问题。然后才能在通信的基础上开发各种应用功能。,第一页 最后一页,吉林大学软件学院,3实现网间进程通信必须解决的问题 网间进程通信是指网络中不同主机中的应用进程之间的相互通信问题,网间进程通信必须解决以下问题:(1)网间进程的标识问题(2)如何与网络协议栈连接的问题(3)多重协议的识别问题(4)不同的通信服务的问题,第一页 最后一页,吉林大学软件学院,按照OSI七层协议的描述,传输层与网络层在功能上的最大区别是传输层提供进程通信的能力。TCP/IP协议提出了传输层协议端口(protocol port,简称端口)的概念,成功地解决了通信进程

4、的标识问题。传输层是计算机网络中,通信主机内部进行独立操作的第一层,是支持端到端的进程通信的关键的一层。,第一页 最后一页,吉林大学软件学院,2端口的概念,端口是TCP/IP协议族中,应用层进程与传输层协议实体间的通信接口 类似于文件描述符,每个端口都拥有一个叫作端口号(port number)的整数型标识符,第一页 最后一页,吉林大学软件学院,3端口号的分配机制 TCP/IP协议采用了全局分配(静态分配)和本地分配(动态分配)相结合的分配方法。对于TCP,或者UDP,将它们的全部65535个端口号分为保留端口号和自由端口号两部分。保留端口的范围是01023,又称为众所周知的端口或熟知端口(w

5、ell-known port),只占少数,采用全局分配或集中控制的方式,由一个公认的中央机构根据需要进行统一分配,静态地分配给因特网上著名的众所周知的服务器进程,并将结果公布于众。,第一页 最后一页,吉林大学软件学院,4进程的网络地址的概念 在因特网络中,用一个三元组可以在全局中唯一地标识一个应用层进程:应用层进程地址=(传输层协议,主机的IP地址,传输层的端口号)这样一个三元组,叫做一个半相关(half-association),它标识了因特网中,进程间通信的一个端点,也把它称为进程的网络地址。,第一页 最后一页,吉林大学软件学院,5网络中进程通信的标识 一个完整的网间通信需要一个五元组在全

6、局中唯一地来标识:(传输层协议,本地机IP地址,本地机传输层端口,远地机IP地址,远地机传输层端口)这个五元组称为一个全相关(association)。即两个协议相同的半相关才能组合成一个合适的全相关,或完全指定一对网间通信的进程。,第一页 最后一页,吉林大学软件学院,1面向消息的协议与基于流的协议(1)面向消息的协议 面向消息的协议以消息为单位在网上传送数据,在发送端,消息一条一条地发送,在接收端,也只能一条一条地接收,每一条消息是独立的,消息之间存在着边界。,1.1.3 网络协议的特征,第一页 最后一页,吉林大学软件学院,(2)基于流的协议 基于流的协议不保护消息边界,将数据当作字节流连续

7、地传输,不管实际消息边界是否存在。,第一页 最后一页,吉林大学软件学院,2面向连接的服务和无连接的服务 一个协议可以提供面向连接的服务,或者提供无连接的服务。面向连接服务是电话系统服务模式的抽象,即每一次完整的数据传输都要经过建立连接,使用连接,终止连接的过程。无连接服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。,第一页 最后一页,吉林大学软件学院,3可靠性和次序性 可靠性保证了发送端发出的每个字节都能到达既定的接收端,不出错,不丢失,不重复,保证数据的完整性,称为保证投递。次序性是指对数据到达接收端的顺序进行处理。保护次序性的协议保证接收端收到数据的顺序就是

8、数据的发送顺序,称为按序递交。,第一页 最后一页,吉林大学软件学院,高效的用户数据报协议UDP 传输层的用户数据报协议(User Datagram Protocol,UDP)是一种尽力传送的无连接的不保障可靠的传输服务,是一种保护消息边界的数据的传输。,第一页 最后一页,吉林大学软件学院,1.1.5 可靠的传输控制协议TCP,1可靠性是很多应用的基础 2TCP为应用层提供的服务 传输控制协议(Transmission Control Protocol,TCP)应用层进程提供一个面向连接的、端到端的、完全可靠的(无差错、无丢失、无重复或失序)全双工的流传输服务。,第一页 最后一页,吉林大学软件学

9、院,TCP被称作一种端对端(end to end)协议,这是因为它提供一个直接从一台计算机上的应用进程到另一远程计算机上的应用进程的连接。应用进程能请求TCP构造一个连接,通过这个连接发送和接收数据,以及关闭连接。由TCP提供的连接叫做虚连接(virtual connection),虚连接是由软件实现的。事实上,底层的因特网系统并不对连接提供硬件或软件支持,只是两台机器上的TCP软件模块通过交换消息来实现连接的幻象。,3TCP利用IP数据报实现了端对端的传输服务,第一页 最后一页,吉林大学软件学院,第2章 UNIX中的套接字网络编程接口,UNIX套接字网络编程接口的产生与发展过程套接字与UNI

10、X操作系统的关系套接字编程的基本概念面向连接的套接字编程无连接的套接字编程,最后一页,吉林大学软件学院,套接字应用程序编程接口是网络应用程序通过网络协议栈进行通信时所使用的接口,即应用程序与协议栈软件之间的接口,简称套接字编程接口(Socket API)。它定义了应用程序与协议栈软件进行交互时可以使用的一组操作,决定了应用程序使用协议栈的方式、应用程序所能实现的功能、以及开发具有这些功能的程序的难度。,第一页 最后一页,吉林大学软件学院,2.1 UNIX套接字网络编程接口的产生与发展,加州大学伯克利(Berkley)分校开发并推广了一个包括TCP/IP互联协议的UNIX,称为BSD UNIX(

11、Berkeley Software Distribution UNIX)操作系统,套接字编程接口是这个操作系统的一个部分。后来的许多操作系统并没有另外搞一套其它的编程接口,而是选择了对于套接字编程接口的支持。由于这个套接字规范最早是由Berkeley大学开发的,一般将它称为Berkeley Sockets规范。,2.1.2 套接字编程接口的起源与应用,第一页 最后一页,吉林大学软件学院,要想实现套接字编程接口,可以采用两种实现方式,一种是在操作系统的内核中增加相应的软件来实现,一种是通过开发操作系统之外的函数库来实现。,2.1.3 套接字编程接口的两种实现方式,第一页 最后一页,吉林大学软件学

12、院,UNIX操作系统对文件和所有其它的输入/输出设备采用一种统一的的操作模式,就是“打开-读-写-关闭”(open-read-write-close)的I/O模式。当TCP/IP协议被集成到UNIX内核中的时候,相当于在UNIX系统中引入了一种新型的I/O操作,就是应用程序通过网络协议栈来交换数据。,2.1.4 套接字通信与UNIX操作系统的输入/输出,第一页 最后一页,吉林大学软件学院,在UNIX系统的实现中,套接字是完全与其他I/O集成在一起的。操作系统和应用程序都将套接字编程接口也看作一种输入/输出机制。但是,用户进程与网络协议的交互作用实际要比用户进程与传统的I/O设备相互作用要复杂得

13、多。,第一页 最后一页,吉林大学软件学院,2.2 套接字编程的基本概念,套接字是对网络中不同主机上应用进程之间进行双向通信的端点的抽象,一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议栈交换数据的机制。,图2.1 电插座与电话插座的作用,2.2.1 什么是套接字(SOCKET),第一页 最后一页,吉林大学软件学院,我们应当从多个层面来理解套接字这个概念的内涵。从套接字所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议栈进行通信的接口,是应用程序与网络协议栈进行交互的接口。,第一页 最后一页,吉林大学软件学院,从实现的角度来讲,非常复杂。套接字是一个复杂的

14、软件机构,包含了一定的数据结构,包含许多选项,由操作系统内核管理。从使用的角度来讲,非常简单。对于套接字的操作形成了一种网络应用程序的编程接口(API)。本书把这一套操作套接字的编程接口函数称作套接字编程接口,套接字是它的操作对象。总之,套接字是网络通信的基石。,第一页 最后一页,吉林大学软件学院,1通信域 接字存在于通信域中,通信域是为了处理一般的进程通过套接字通信而引入的一种抽象概念,套接字通常只和同一域中的套接字交换数据。如果数据交换要穿越域的边界,就一定要执行某种解释程序。现在,仅仅针对Internet域,并且使用Internet协议族(即TCP/IP协议族)来通信。,2.2.2 套接

15、字的特点,第一页 最后一页,吉林大学软件学院,2套接字具有三种类型 每一个正被使用的套接字都有它确定的类型,只有相同类型的套接字才能相互通信。(1)数据报套接字(Datagram SOCKET)数据报套接字提供无连接的不保证可靠的独立的数据报传输服务。在Internet通信域中,数据报套接字使用UDP数据报协议形成的进程间通路,具有UDP协议为上层所提供的服务的所有特点。,第一页 最后一页,吉林大学软件学院,(2)流式套接字(Stream SOCKET)流式套接字提供双向的、有序的、无重复的、无记录边界的可靠的数据流传输服务。在Internet通信域中,流式套接字使用TCP协议形成的进程间通路

16、,具有TCP协议为上层所提供的服务的所有特点,在使用流式套接字传输数据之前,必须在数据的发送端和接收端之间建立连接。,第一页 最后一页,吉林大学软件学院,(3)原始式套接字(RAW SOCKET)原始式套接字允许对较低层次的协议,如IP、ICMP直接访问,用于检验新的协议的实现。,第一页 最后一页,吉林大学软件学院,3套接字的创建套接字由应用层的通信进程创建,并为其服务就是说,每一个套接字都有一个相关的应用进程,操作该套接字的代码是该进程的组成部分。,第一页 最后一页,吉林大学软件学院,4使用确定的IP地址和传输层端口号,往往在生成套接字的描述符后,要将套接字与计算机上的特定的IP地址和传输层

17、端口号相关联,这个过程称为绑定。一个套接口要使用一个确定的三元组网络地址信息,才能使它在网络中唯一地被标识。,第一页 最后一页,吉林大学软件学院,(1)不管是采用对等模式或者客户机/服务器模式,通信双方的应用程序都需要开发。(2)双方所交换数据的结构和交换数据的顺序有特定的要求,不符合现在成熟的应用层协议,甚至需要自己去开发应用层协议,自己设计最适合的数据结构和信息交换规程。,2.2.3 套接字的应用场合,第一页 最后一页,吉林大学软件学院,本机字节顺序和网络字节顺序 在具体计算机中的多字节数据的存储顺序,称为本机字节顺序。多字节数据在网络协议报头中的存储顺序,称为网络字节顺序。,第一页 最后

18、一页,吉林大学软件学院,网络应用程序要在不同的计算机中运行,本机字节顺序是不同的,但是,网络字节顺序是一定的。所以,应用程序在编程的时候,在把IP地址和端口号装入套接字的时候,应当把它们从本机字节顺序转换为网络字节顺序;相反,在本机输出时,应将它们从网络字节顺序转换为本机字节顺序。,第一页 最后一页,吉林大学软件学院,通常,我们使用域名来标识站点,可以将文字型的主机域名直接转换成IP地址,struct hostent*gethodtbyname(const char*name);入口参数:是站点的主机域名字符串,返回值:是指向hostent 结构的指针,hostent结构包含主机名,主机别名数

19、组,返回地址的类型(一般是AF-INET),地址长度的字节数,已符合网络字节顺序的主机网络地址等。,域名服务,第一页 最后一页,吉林大学软件学院,2.3 面向连接的套接字编程,第一页 最后一页,吉林大学软件学院,1创建套接字SOCKET()SOCKET过程创建一个套接字并返回一个整型描述符:int SOCKET(int Protofamily,int Type,int Protocol);,第一页 最后一页,吉林大学软件学院,2.3 面向连接的套接字编程,2绑定套接字到指定的地址 BIND()int BIND(int Sockfd,struct sockaddr*My_addr,int Add

20、rlen);3启动监听Listen()int LISTEN(int Sockfd,int Queuesize);4接收连接请求ACCEPT()int ACCEPT(int Sockfd,struct sockaddr*Addr,int*addrlen);,第一页 最后一页,吉林大学软件学院,5请求建立连接CONNECT()int CONNECT(int Sockfd,struct sockaddr*Service_addr,int Addrlen);举例:if(CONNECT(sockfd,(struct sockaddr*)(&serv_addr),sizeof(struct sockadd

21、r)0)报错,并退出,第一页 最后一页,吉林大学软件学院,6读/写套接字READ()和WRITE()int READ(int sockfd,void*buffer,int len)int WRITE(int sockfd,void*buffer,int len)7发送 SEND()和接收 RECV()int SEND(int sockfd,char*buf,int len,int flags);int RECV(int sockfd,char*buf,int len,int flags);8关闭套接字CLOSE()int CLOSE(int sockfd);,第一页 最后一页,吉林大学软件学院

22、,2.3.4 进程的阻塞问题和对策,1什么是阻塞 阻塞是指一个进程执行了一个函数或者系统调用,该函数由于某种原因不能立即完成,因而不能返回调用它的进程,导致进程受控于这个函数而处于等待的状态,进程的这种状态称为阻塞。,第一页 最后一页,吉林大学软件学院,2能引起阻塞的套接字调用 在Berkeley套接字网络编程接口的模型中,套接字的默认行为是阻塞的,具体地说,在一定情况下,有多个操作套接字的系统调用会引起进程阻塞。(1)ACCEPT()(2)READ()、RECV()和READFORM()(3)WRITE()、SEND()和SENDTO()(4)CONNECT()(5)SELECT()(6)C

23、LOSESOCKET(),第一页 最后一页,吉林大学软件学院,2.4 无连接的套接字编程2.4.1 无连接的套接字编程的两种模式 使用数据报套接字开发网络应用程序,既可以采用客户/服务器模式,也可以采用对等模式。,第一页 最后一页,吉林大学软件学院,2.4.2 两个专用的系统调用1发送数据报SENDTO()int SENDTO(int sockfd,const void*msg,int len,unsigned int flags,struct sockaddr*to,int tolen);2接收数据报 RECVFROM()int RECVFROM(int sockfd,void*buf,in

24、t len,unsigned int flags,struct sockaddr*from,int*fromlen),第一页 最后一页,吉林大学软件学院,第3章 Windows环境的网络编程内容提要:Windows Sockets 规范 WinSock 规范与Berkeley套接口的区别 Winsock 1.1 的库函数,3.1 Windows Sockets规范3.1.1 概述Microsoft公司以Berkeley Sockets规范为范例,定义了Windows Socktes规范,简称Winsock规范。这是Windows操作系统环境下的套接字网络应用程序编程接口(API)。,3.1.2

25、 Windows Sockets规范 Windows Sockets 规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年到1995年,从1.0版发展到版,已成为Windows网络编程的事实上的标准。1Windows Sockets 1.1版本 在Winsock.h包含文件中,定义了所有WinSock 1.1版本库函数的语法、相关的符号常量和数据结构。库函数的实现在WINSOCK.DLL动态链接库文件中。,(1)WinSock 1.1 全面继承了Berkeley Sockets规范(2)数据库函数Winsock规范定义了数据库查询例程,其中六个采用getXbyY()的形

26、式,大多要借助网络上的数据库来获得信息,(3)WinSock 1.1扩充了Berkeley Sockets规范针对微软 Windows的特点,WinSock 1.1定义了一批新的库函数,提供了对于消息驱动机制的支持,有效地利用Windows多任务多线程的机制。(4)WinSock 1.1只支持TCP/IP协议栈,2WinSock 2.0WinSock 2.0在源码和二进制代码方面与WinSock 1.1兼容,WinSock 2.0增强了许多功能。(1)支持多种协议(2)引入了重叠I/O的概念(3)使用事件对象异步通知(4)服务的质量(QOS)(5)套接口组(6)扩展的字节顺序转换例程(7)分散

27、/聚集方式I/O(8)新增了许多函数。,3WinSock 1.1中的阻塞问题 阻塞是在把应用程序从Berkeley套接口环境中移植到Windows环境中的一个主要焦点。阻塞是指唤起一个函数,该函数直到相关操作完成时才返回。在Berkeley套接口模型中,一个套接口的操作的缺省行为是阻塞方式的,除非程序员显式地请求该操作为非阻塞方式。在Windows环境下,我们强烈推荐程序员在尽可能的情况下使用非阻塞方式(异步方式)的操作。因为非阻塞方式的操作能够更好地在非占先的Windows环境下工作。,3.1.3 WinSock规范与Berkeley套接口的区别1套接口数据类型和该类型的错误返回值 在UNI

28、X中,包括套接口句柄在内的所有句柄,都是非负的短整数,在WinSock规范中定义了一个新的数据类型,称作SOCKET,用来代表套接字描述符。typedef u_int SOCKET;SOCKET可以取从0到INVALID_SOCKET-1之间的任意值。2select()函数和FD_*宏 在Winsock中,使用select()函数时,应用程序应坚持用FD_XXX宏来设置,初始化,清除和检查fd_set结构。,3错误代码的获得 在UNIX 套接字规范中,如果函数执行时发生了错误,会把错误代码放到errno或h_errno变量中。在Winsock中,错误代码可以使用WSAGetLastError(

29、)调用得到。4指针 所有应用程序与Windows Sockets使用的指针都必须是FAR指针。5重命名的函数(1)close()改变为closesocket()(2)ioctl()改变为ioctlsocket(),6Winsock支持的最大套接口数目 在WINSOCK.H中缺省值是64,在编译时由常量FD_SETSIZE决定。7头文件 Berkeley头文件被包含在WINSOCK.H中。一个Windows Sockets应用程序只需简单地包含WINSOCK.H就足够了。8Winsock规范对于消息驱动机制的支持 体现在异步选择机制、异步请求函数、阻塞处理方法、错误处理、启动和终止等方面。,第6

30、章 WinSock的多线程编程WinSock需要多线程编程的原因,Win32操作系统下的多进程多线程机制、多线程机制在网络编程中的应用和Visual C+6.0对多线程网络编程的支持。进而分析了MFC支持的两种线程,给出了创建MFC的工作线程、创建并启动用户界面线程和终止线程的步骤。,6.1 WinSock为什么需要多线程编程6.1.1 WinSock的两种输入输出模式如前所述,WinSock在进行输入输出的时候,可以使用两种工作模式。即“阻塞”模式(Blocking Mode)或“非阻塞”模式,又称为同步模式或异步模式。工作在“阻塞”模式的套接字称为阻塞套接字,工作在“非阻塞”模式下的套接字

31、称为非阻塞套接字。,6.1.2 两种模式的优缺点及解决方法“阻塞”与“非阻塞”模式各有其优点和缺点。阻塞套接字的I/O操作工作情况比较确定,无非是调用、等待、返回。大部分情况下,I/O操作都能成功地完成,不过就是花费了等待的时间。因而比较容易使用,容易编程;但在应付诸如需要建立多个套接字连接来为多个客户服务的时候,或在数据的收发量不均匀的时候,或在输入输出的时间不确定的时候,却显得性能低下,甚至无能为力。,使用非阻塞套接字,需要编写更多的代码,因为必须恰当地把握调用I/O函数的时机,尽量减少无功而返的调用,还必须详加分析每个Winsock调用中收到的WSAEWOULDBLOCK错误,采取相应的

32、对策,这种I/O操作的随机性使得非阻塞套接字显得难于操作。所以,我们必须采取一些适当的对策,克服这两种模式的缺点,让阻塞和非阻塞套接字能够满足各种场合的要求。对于非阻塞的套接字工作模式,进一步引入了五种“套接字I/O模型”,在第8章详细说明。对于阻塞的套接字工作模式,则进一步引入了多线程机制。,6.2 Win32操作系统下的多进程多线程机制6.2.1 Win32是单用户多任务的操作系统最早的DOS是单用户单任务的。后来发展到图形界面的Windows,发展到Windows 95,Windows 98,就都支持多任务了,从Windows NT起,Windows操作系统更是发展成了一个真正的抢占式多

33、任务操作系统。,6.2.2 Win32 OS是支持多线程的操作系统 Win32操作系统还支持同一进程的多线程。在一个Windows进程内,可以包含多个线程。一个线程(thread)是进程内的一条执行路径,具体地说,是一个应用程序中的一条可执行路径,往往是应用程序中的一个或多个函数。一个进程中至少要有一个线程,习惯将它称为主线程。任何一个应用程序进程都有一个主线程。一般C程序中的Main或WinMain函数就规定了主线程的执行代码。当你启动了一个应用程序时,操作系统在为它创建了进程之后,也创建了该进程的主线程,并根据Main或WinMain函数的地址,开始执行该进程的主线程。主线程可以创建并启动

34、其他辅助线程,由主线程创建的线程又可以创建并启动更多的线程。,一个线程也需要占用一定的系统资源,线程是进程中相对独立的执行单位,也是Win32操作系统中可调度的最小的执行单位。多个进程中的多个线程并发地执行。对于拥有多个处理机的计算机系统,调度程序可以将不同的线程安排到不同的处理机上去运行,一方面平衡了CPU的负载,另一方面也提高了系统的运行效率。当某个线程的代码都执行完毕时,该线程会自动终止;当一个线程终止时,会将它所占用的资源释放给进程。,6.2.3 多线程机制在网络编程中的应用如果一个应用程序,有多个任务需要同时进行处理,那就最适合使用多线程机制。对于网络上客户机软件,采用多线程的编程技

35、术,能克服在单线程的编程模式下,由于阻塞等待而产生的客户程序就不能及时响应用户的操作命令的问题。对于网络上服务器软件,采用多线程的编程技术,能更好地为多个客户服务。即便是对于一个客户,采用多线程机制也能大大提高应用程序的运行效率。比如大家熟悉的东方快车、网络蚂蚁等文件下载软件,就采用了多线程机制,用多个线程同时下载一个文件的不同部分,大大加快了下载速度。总之,多线程机制在网络编程中是大有作为的。,6.3 Visual C+6.0对多线程网络编程的支持 Visual C+6.0为程序员提供了Windows应用程序的集成开发环境,在这个环境下,有两种开发程序的方法。既可以直接使用Win32 API

36、来编写C风格的Win32应用程序,也可以利用MFC基础类库编写C+风格的应用程序。在这两种Windows应用程序的开发方式下,多线程的编程原理是一致的。,6.3.1 MFC支持的两种线程 微软的基础类库MFC提供了对于多线程应用程序的支持。在MFC中,线程分为两种,一种是用户接口线程(user-interface thread),或称用户界面线程;另一种是工作线程(the worker thread),这两类线程可以满足不同任务的处理需求。,1用户接口线程 用户接口线程通常用来处理用户输入产生的消息和事件,并独立地响应正在应用程序其它部分执行的线程们产生的消息和事件,MFC特别地为用户接口线程

37、提供了一个消息泵(a message pump)。用户接口线程包含一个消息处理的循环,以应对各种事件。在MFC应用程序中,所有的线程都是由CWinThread对象来表示的。CWinThread类(可以理解为C+的Windows 线程类)是用户接口线程的基类,CWinApp就是从CWinThread类派生出来的,我们在编写用户接口线程的时候,也需要从CWinThread类派生出自己的线程类,借助ClassWizard可以很容易地做这项工作。,2工作线程 工作线程(the worker thread),适用于处理那些不要求用户输入并且比较消耗时间的其他任务。对用户来说,工作线程运行在后台。这就使得

38、工作线程特别适合去等待一个事件的发生。CWinThread类同样是工作线程的基类,同样是由CWinThread对象来表示的。但在编写工作线程的时候,你甚至不必刻意地从CWinThread类派生出自己的线程类对象。你可以调用MFC框架的AfxBeginThread帮助函数,它会为你创建CWinThread对象。,第7章 Winsock的输入/输出模型 第6章已经提到,WinSock在进行输入输出的时候,可以采用阻塞模式或非阻塞模式。使用非阻塞套接字,带有I/O操作的随机性,使非阻塞套接字难于操作,给编程带来困难。为解决这个问题,对于非阻塞的套接字工作模式,进一步引入了五种“套接字I/O模型”,它

39、们有助于应用程序通过一种异步方式,同时对一个或多个套接字上进行的通信加以管理。,这些模型包括:select(选择)WSAAsyncSelect(异步选择)WSAEventSelect(事件选择)Overlapped I/O(重叠式I/O)Completion port(完成端口)不同的Windows平台支持不同的I/O模型。如表7.1所示:,表7.1 操作系统对套接字I/O模型的支持情况,7.1 select模型 select(选择)模型是Winsock中最常见的I/O模型。它的中心思想是利用select函数,实现对多个套接字I/O的管理。利用select函数,可以判断套接字上是否存在数据,或

40、者能否向一个套接字写入数据。只有在条件满足时,才对套接字进行输入输出操作,从而避免无功而返的I/O函数调用,避免频繁产生WSAEWOULDBLOCK错误,使输入输出变得有序。,1select的函数select的函数原型如下,其中fd_set数据类型,代表着一系列特定套接字的集合。int select(int nfds,fd_set FAR*readfds,fd_set FAR*writefds,fd_set FAR*exceptfds,const struct timeval FAR*timeout);,2操作套接字集合的宏在应用程序中,用select对套接字进行监视之前,必须先将要检查的套接

41、字句柄分配给某个集合,设置好相应的fd_set结构,再来调用select函数,便可知道一个套接字上是否正在发生上述的I/O活动。Winsock提供了4个宏操作,专门对fd_set数据类型进行操作(1)FD_CLR(s,*set):从set中删除套接字s。,(2)FD_ISSET(s,*set):检查s是否set集合的一名成员;如果是,则返回TRUE。(3)FD_SET(s,*set):将套接字s加入集合set。(4)FD_ZERO(*set):将set初始化成空集合。其中,参数s是一个要检查的套接字,参数set是一个fd_set集合类型的指针。例如,调用select函数前,可使用FD_SET宏

42、,将指定的套接字加入到fd_read集合中,select函数完成后,可使用FD_ISSET宏,来检查该套接字是否仍在fd_read集合中。,3select模型的操作步骤用select操作一个或多个套接字句柄,一般采用下述步骤:(1)使用FD_ZERO宏,初始化自己感兴趣的每一个fd_set集合。(2)使用FD_SET宏,将要检查的套接字句柄添加到自己感兴趣的每个fd_set集合中,相当在指定的fd_set集合中,设置好要检查的I/O活动。,(3)调用select函数,然后等待。select完成返回后,会修改每个fd_set结构,删除那些不存在待决I/O操作的套接字句柄,在各个fd_set集合中

43、返回符合条件的套接字。(4)根据select的返回值,使用FD_ISSET宏,对每个fd_set集合进行检查,判断一个特定的套接字是否仍在集合中,便可判断出哪些套接字存在尚未完成(待决)的I/O操作。(5)知道了每个集合中“待决”的I/O操作之后,对相应的套接字的I/O进行处理,然后返回步骤1,继续进行select处理。,7.2 WSAAsyncSelect异步I/O模型异步I/O模型通过调用WSAAsyncSelect()函数实现。利用这个模型,应用程序可在一个套接字上,接收以Windows消息为基础的网络事件通知。该模型最早出现于Winsock的1.1中,以适应其多任务消息环境。,1WSA

44、AsyncSelect函数函数的定义是:int WSAAsyncSelect(SOCKET s,HWND hWnd,unsigned int wMsg,long lEvent);,2窗口回调例程 应用程序在一个套接字上调用WSAAsyncSelect函数时,该函数的hWnd参数指定了一个窗口句柄。函数成功调用后,当指定的网络事件发生时,会自动执行该窗口对应的窗口回调例程。并将网络事件通知和Windows消息的相关信息,传递给该例程的入口参数,用户可以在该例程中添加自己的代码,针对不同的网络事件进行处理,从而实现有序的套接字输入和输出。,窗口回调例程应定义成如下形式:LRESULT CALLBA

45、CK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);,7.3 WSAEventSelect事件选择模型 WSAEventSelect事件选择模型和WSAAsyncSelect模型类似,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知。表7.2总结的、由WSAAsyncSelect模型采用的网络事件,均可原封不动地移植到事件选择模型中。也就是说,在用新模型开发的应用程序中,也能接收和处理所有那些事件。该模型最主要的差别在于,网络事件会投递至一个事件对象句柄,而非投递至一个窗口例程。,1创建事件对象句柄事

46、件选择模型要求应用程序针对每一个套接字,首先创建一个事件对象。创建方法是调用WSACreateEvent函数,它的定义如下:WSAEVENT WSACreateEvent(void);函数的返回值很简单,就是一个创建好的事件对象句柄。,2关联套接字和事件对象,注册关心的网络事件有了事件对象句柄后,接下来必须将其与某个套接字关联在一起,同时注册感兴趣的网络事件类型(表7.2),这就需要调用WSAEventSelect函数,函数的定义为:int WSAEventSelect(SOCKET s,WSAEVENT hEventObject,long lNetworkEvents);调用:WSAAsyn

47、cSelect(s,hwnd,WM_SOCKET,FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);,表7.2 用于WSAAsyncSelect函数的网络事件类型,3.等待网络事件触发事件对象句柄的工作状态将一个套接字同一个事件对象句柄关联在一起以后,应用程序便可以调用WSAWaitForMultipleEvents函数,等待网络事件触发事件对象句柄的工作状态。该函数用来等待一个或多个事件对象句柄,当其中一个或所有句柄进入“已传信”状态后,或在超过了一个规定的时间期限后,立即返回。该函数的定义:DWORD WSAWaitForMultipleEvents(DWORD

48、cEvents,const WSAEVENT FAR*lphEvents,BOOL fWaitAll,DWORD dwTimeout,BOOL fAlertable);,4检查套接字上所发生的网络事件类型知道了造成网络事件的套接字后,接下来可调用WSAEnumNetworkEvents函数,检查套接字上发生了什么类型的网络事件。该函数定义如下:int WSAEnumNetworkEvents(SOCKET s,WSAEVENT hEventObject,LPWSANETWORKEVENTS lpNetworkEvents);,5处理网络事件在确定了套接字上发生的网络事件类型后,可以根据不同的情

49、况做出相应的处理。完成了对WSANETWORKEVENTS结构中的事件的处理之后,应用程序应在所有可用的套接字上,继续等待更多的网络事件。应用程序完成了对一个事件对象的处理后,便应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。函数的定义如下:BOOL WSACloseEvent(WSAEVENT hEvent);该函数也将一个事件句柄作为自己唯一的参数,并会在成功后返回TRUE,失败后返回FALSE。,7.4 其他模型 在Winsock中,重叠I/O(Overlapped I/O)模型能使应用程序达到更佳的性能。重叠模型的基本原理是让应用程序使用一个重叠的数据结构,一次投递

50、一个或多个Winsock的I/O请求。针对那些提交的请求,在它们完成之后,应用程序可为它们提供服务。自Winsock 2.0发布开始,重叠I/O便已集成到新的Winsock函数中,比如WSASend和WSARecv等。因此,重叠I/O模型适用于安装了Winsock 2.0的所有Windows平台。,“完成端口”模型是迄今为止最为复杂的一种I/O模型。然而,假若一个应用程序同时需要管理为数众多的套接字,那么采用这种模型,往往可以达到最佳的系统性能!该模型只适用于Windows NT和Windows 2000操作系统。因其设计的复杂性,只有在你的应用程序需要同时管理数百乃至上千个套接字的时候,而且

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号