《Windows网络程序设计(夏靖波) 第3章》由会员分享,可在线阅读,更多相关《Windows网络程序设计(夏靖波) 第3章(83页珍藏版)》请在金锄头文库上搜索。
1、第3章 WinSock基础,3.1 基本概念 3.2 WinSock编程原理 3.3 WinSock I/O模型 3.4 WinSock 2的扩展特性 3.5 套接字选项和I/O控制命令 习题与思考题,3.1 基 本 概 念,3.1.1 套接字及类型 套接字(socket)是网络通信的基本构件,是可以被命名和寻址的通信端点,使用中的每一个套接字都有其类型和与之相连的进程。 套接字存在于通信区域中,通信区域也称地址族,是个抽象概念,主要用于将通过套接字通信的进程的共有特性综合在一起。套接字通常只与同一区域中的套接字交换数据(也可跨区域通信,但要执行某种转换进程之后才能实现)。Windows So
2、ckets只支持一个通信区域:网际域(AF-INET),这个域被使用网际协议族通信的进程所使用。,套接字都具有不同类型,是根据用户可见的通信特征进行分类的。应用程序被假定为只在同一类型的套接字间通信,不过只要通信协议支持,也可在不同类型的套接字间通信。 TCP/IP的socket提供三种类型的套接字: * 流式套接字(SOCK_STREAM):提供一个面向连接的、可靠的数据传输服务,数据无差错、无重复地发送,且按发送顺序接收。内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制。文件传输协议(FTP)即使用流式套接字。,* 数据报式套接字(SOCK_DGRAM):提供一个无连接服务。数
3、据报以独立包形式被发送,不提供无错保证,数据可能丢失或重复,且接收顺序混乱。网络文件系统(NFS)使用数据报式套接字。 * 原始式套接字(SOCK_RAW):该接口允许对较低层协议,如IP、ICMP直接访问。常用于检验新的协议实现或访问现有服务中配置的新设备。,3.1.2 网间进程通信 1. 端口 网络中可以被命名和寻址的通信端口是操作系统可分配的一种资源。按照OSI协议的描述,传输层与网络层在功能上的最大区别是传输层提供进程通信,从这个意义上讲,网络通信的最终地址不仅仅是主机地址,还包括可以描述进程的某种标识符。为此,TCP/IP协议提出可协议端口(protocol port,简称端口)的概
4、念,用于标识通信的进程。,端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序(进程)通过系统调用与某端口建立连接(binding)后,传输层传给该端口的数据都被相应进程所接收,相应进程发给传输层的数据都通过该端口输出。在TCP/IP协议的实现中,端口操作类似一般的I/O操作,进程获取一个端口,相当于获取本地唯一的I/O文件。 类似于文件描述符,每个端口都拥有一个叫端口号(port number)的整数型标识符,用于区别不同的端口。由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立。,端口号的分配是个重要问题,有两种基本分配方式:
5、全局分配和本地分配。全局分配是一种集中控制方式,由一个公认的中央机构根据用户需要进行统一分配,并将结果公布于众。本地分配又称动态连接,即进程需要访问传输层服务时,向本地操作系统提出申请,操作系统返回一个本地唯一的端口号,进程再通过合适的系统调用,将自己与该端口号联系起来。TCP/IP中端口号的分配综合了上述两种方式,TCP/IP将端口号分为两部分,少量的作为保留端口,以全局方式分配给服务进程,因此每个标准服务器都拥有一个全局公认的端口即周知口(well-known port),即使在不同机器上,其端口号也相同。剩余的为自由端口,以本地方式进行分配。TCP和UDP均规定,小于256的端口号才能作
6、保留端口。,2. 地址 网络通信中通信的两个进程在不同的机器上。这两个机器可能位于不同的网络,这些网络通过网络互联设备(网关、网桥、路由器等)连接。因此需要如下三级寻址: * 某一主机与多个网络相连,必须指定一特定网络地址; * 网络上每一主机应有唯一的地址; * 每一主机上的每一进程应有在该主机上的唯一标识符。 通常主机地址由网络ID和主机ID组成,在TCP/IP协议中用32位整数值表示;TCP和UDP均使用16位端口号标识用户进程。,3. 网络字节顺序 不同计算机存放多字节值的顺序不同,为保证数据的正确性,在网络协议中需要指定网络字节顺序。TCP/IP协议使用16位整数和32位整数的高位先
7、存格式,它们均含在协议头文件中。 4. 连接 两个进程间的通信链路称为连接。连接在内部表现为一些缓冲区和一组协议机制,在外部表现出比无连接高的可靠性。,5. 半相关 综上所述,网络中用一个三元组(协议,本地地址,本地端口号)可以在全局唯一标志一个进程,这个三元组叫半相关(half-association),它指定连接的每半部分。 6. 全相关 一个完整的网间进程通信需要由两个进程组成,且只能使用同一种高层协议。即不可能通信的一端用TCP协议,另一端用UDP协议。因此一个完整的网间通信需要用一个五元组(协议,本地地址,本地端口号,远地地址,远地端口号)来标识,这个五元组叫全相关(associat
8、ion),即两个协议相同的半相关才能组成一个合适的相关,或完全指定组成一连接。,3.1.3 服务方式 1. 面向连接(虚电路)或无连接 面向连接服务是电话系统服务模式的抽象,每一次完整的数据传输都要经过建立连接、使用连接、终止连接的过程。在数据传输过程中,各数据分组但不携带目的地址,而使用连接号(connect ID)。本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。TCP协议提供面向连接的虚电路。 无连接服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。无连接服务不能保证分组的先后顺序,不进行分组出错的恢复和重传,不保证传输的可靠性。UDP协议提供无
9、连接的数据报服务。,2. 顺序 在网络传输中,两个连续报文在端到端通信中可能经过不同的路径,这样到达目的地址时的顺序可能与发送时不同。“顺序”是指接收数据顺序与发送数据顺序相同。TCP协议提供这项服务。 3. 差错控制 差错控制是保证应用程序接收的数据无差错的一种机制。检查差错的方法一般是采用检验“校验和”(Checksum)的方法,而保证传输无差错的方法是双方采用确认应答技术。TCP协议提供这项服务。,4. 流控制 流控制是在数据传输过程中控制数据传输速率的一种机制,以保证数据不丢失。TCP协议提供这项服务。 5. 字节流 字节流方式是指仅把传输中的报文看作是一个字节序列,不提供数据流的任何
10、边界。TCP协议提供这项服务。 6. 报文 接收方要保存发送方的报文边界。UDP协议提供这项服务。,7. 全双工/半双工 全双工/半双工是指端与端之间的数据同时向两个方向或一个方向传送。 8. 缓存/带外数据 在字节流服务中,由于没有报文边界,用户进程在某一时刻可以读/写任意数量的字节。为保证传输正确或采用有流控制的协议,都要进行缓存。但对某些特殊的需求,如交互式应用程序,又会要求取消这种缓存。,3.1.4 客户机/服务器模式 在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机/服务器模式(Client/Server Model),即客户机向服务器发出服务请求,服务器接收到请
11、求后,提供相应的服务。客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软/硬件资源、运算能力和信息不均等,需要共享,从而形成拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对称的情况。其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户机/服务器模式的TCP/IP。,客户机/服务器模式在操作过程中采取主动请求方式: (1) 服务器方启动,并根据请求提供相应的服务: * 打开一通信通道并告知本地主机,它愿意在某公认地址(如FTP:21)上接收客户请求。
12、* 等待客户请求到达该端口。 * 接收到重复服务请求,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求(如UNIX系统中用fork、exec)。新进程处理此客户请求,并不需要对其他请求作出应答。 * 返回第二步,等待另一客户请求。 * 关闭服务器。,(2) 客户机方: * 打开一通信通道,并连接到服务器所在地的主机特定端口。 * 向服务器发送服务请求报文,等待并接收应答,继续提出请求。 * 请求结束后关闭通信通道并终止。 从上面描述的过程可知: * 客户机与服务器进程的作用是非对称的,因此编码不同。 * 服务进程一般是先于客户机请求而启动的,只要系统运行,该服务进
13、程一直存在,直到正常终止或强迫终止。,3.1.5 WinSock对Socket的扩充 Windows Sockets是从Berkeley Sockets扩展而来的,并在继承Berkeley Sockets的基础上进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制。 Windows Sockets由两部分组成:开发组件和运行组件。开发组件:Windows Sockets 实现文档、应用程序接口(API)引入库和一些头文件。运行组件:Windows Sockets应用程序接口的动态链接库(Winsock.dll)。,1. 异步选择机制 W
14、indows Sockets的异步选择函数提供了消息机制的网络事件选择,当使用它登记的网络事件发生时,Windows应用程序相应的窗口函数将收到一个消息,消息中指示了发生的网络事件以及与事件相关的一些信息。Windows Sockets提供了一个异步选择函数 WSAAsyncSelect(),用它来注册应用程序感兴趣的网络事件,当这些事件发生时,应用程序相应的窗口函数将收到一个消息。,2. 异步请求函数 异步请求函数允许应用程序用异步方式获得请求的信息,且在请求的服务完成时给应用程序相应的窗口函数发送一个消息。,3. 阻塞处理方法 Windows Sockets为了实现当一个应用程序的套接字调
15、用处于阻塞时,能够放弃CPU让其他应用程序运行,它在调用处于阻塞时便进入一个叫“HOOK”的例程,此例程负责接收和分配Windows消息,这使得其他应用程序仍然能够接收到自己的消息并取得控制权。 Windows是非抢先的多任务环境,即若一个程序不主动放弃其控制权,别的程序就不能执行。因此在设计Windows Sockets程序时,尽管系统支持阻塞操作,但还是不提倡程序员使用该操作。但由于Sun公司下的Berkeley Sockets的套接字默认操作是阻塞的,因此Windows作为移植的Sockets也不可避免对这个操作的支持。,在Windows Sockets实现中,对于不能立即完成的阻塞操作
16、可做如下处理:DLL初始化循环操作。在循环中,它发送任何Windows消息,并检查这个Windows Sockets调用是否完成,在必要时,它可以放弃CPU让其他应用程序执行(当然使用超线程的CPU就不会有这个麻烦了)。我们可以调用WSACancelBlockingCall()函数取消此阻塞操作。,在Windows Sockets中,有一个默认的阻塞处理例程BlockingHook()可简单地获取并发送Windows消息。如果要对复杂的程序进行处理,Windows Sockets中还有WSASetBlockingHook()函数可供用户安装自己的阻塞处理例程;与该函数相对应的则是WSAUnhookBlockingHook(),它用于删除先前安装的任何阻塞处理例程,并重新安装默认的处理例程。注意,设计自己的阻塞处理例程时,除了函数WSACancelBlockingHook()之外,不能使用其他的WinSock API函数。在处理例程中调用WSACancelBlockingHook()函数将取消处于阻塞的操作并结束阻塞循环。,4. 出错处理 Windows Sockets为了和多线程环境