Windows Sockets是Windows环境下的网络编程接口,它源于UNIX环境下的BSD Socket,是一个与网络协议无关的编程接口。
20世纪90年代初,Sun Microsystems、JSB Corporation、FTP Software、Microdyne和微软等公司共同参与了Windows Sockets规范的制定。它们以BSD UNIX中流行的Socket接口为模板,为Windows定义了一套网络编程接口。该接口不但包含人们熟知的Berkeley Socket风格的函数,还包含一组针对Windows的扩展库函数,以便使程序员能够充分利用Windows消息驱动机制进行编程。
Windows Sockets规范的目的在于为应用程序开发者提供一套简单的API,并让各网络软件供应商共同遵守。除此之外,在Windows的特定版本上,还定义了一个二进制接口(ABI),以此来确保使用Windows Sockets API开发且符合Windows Sockets规范的应用程序能够正常工作。可以说,Windows Sockets定义了网络软件供应商能够实现并且应用程序开发者能够使用的一套库函数调用和相关语义。
对于符合Windows Sockets规范的网络软件,一般将其视为与Windows Sockets兼容,将Windows Sockets兼容实现的提供者称为Windows Sockets提供者。一个网络软件供应商必须完全遵循Windows Sockets规范才能做到与Windows Sockets兼容。通常,只要应用程序能够与Windows Sockets兼容,并且能与之协同工作,就将其称为Windows Sockets应用程序。
1.Windows Sockets 1.0
Windows Sockets 1.0是网络软件供应商和用户社区共同努力的结果。Windows Sockets 1.0规范的发布是为了让应用程序开发者能够创建符合Windows Sockets标准的应用程序。
2.Windows Sockets 1.1
Windows Sockets 1.1沿袭了Windows Sockets 1.0的指导思想和结构,包含更加清晰的说明,以及对Windows Sockets 1.0所做的小改动。除此之外,它还包含了一些重要变更,部分变更如下:
· 增加了gethostname()调用,以便简化主机名字和地址的获取。
· 将DLL中小于1000的序数定义为Windows Sockets保留,而对大于1000的序数则没有限制。这使得Windows Sockets供应商可以在自己的DLL中包含私有接口,而不用担心所选择的序数会和未来的Windows Sockets版本冲突。
· 为WSAStartup()和WSACleanup()函数增加了引用计数,并要求两个函数调用时成对出现,在所有Windows Sockets函数之前调用WSAStartup()函数,最后调用WSACleanup()函数。这使得应用程序和第三方DLL在使用Windows Sockets实现时不需要考虑其他程序对这套API的调用。
3.Windows Sockets 2.0
Windows Sockets 2.0是对Windows Sockets 1.1的扩展,通过Windows Sockets 2.0,程序员可以创建高级的Internet、Intranet以及其他网络应用程序。利用这些应用程序,可以在不依赖网络协议的情况下在网上传输应用数据。
创建Windows Sockets 2.0是为了提供一个协议无关的传输接口,并且该接口完全具有支持应急网络的处理能力,包括实时多媒体通信。Windows Sockets 2.0在维持向后完全兼容能力的同时还在很多领域扩展了Windows Sockets接口,包括:
1)体系结构的改变。为了提供同时访问多个传输协议的能力,Windows Sockets的结构在2.0版本下发生了改变。Windows Sockets 2.0通过在Windows Sockets DLL和协议栈之间定义一个标准的服务提供者接口(Service Provider Interface,SPI)改变了原Windows Sockets 1.1和底层协议栈之间的私有接口模式,这使得从单个Windows Sockets DLL中同时访问来自多个厂商的多个协议栈成为可能。Windows Sockets 2.0的体系结构如图2-1所示。
2)套接字句柄的改变。在Windows Sockets 2.0中,套接字句柄可以是文件句柄,这意味着可以将套接字句柄用于Windows文件的I/O函数,如ReadFile()、WriteFile()、ReadFileEx()、WriteFileEx()、DuplicateHandle()等。当然,并非所有的传输服务提供者都支持这个选项,这一点必须注意。
图2-1 Windows Sockets 2.0的体系结构
3)对多协议簇的支持。Windows Sockets 2.0可以使应用程序利用熟悉的套接字接口同时访问其他已安装的传输协议,这是其最重要的特征,而Windows Sockets 1.1则是与TCP/IP协议簇绑定在一起的,仅仅支持TCP/IP协议簇。
4)协议独立的名字解析能力。Windows Sockets 2.0包含了一套标准API以用于现有的大量名字解析域名系统,如DNS、SAP、X.500等。
5)分散/聚集I/O支持。按照在Win32环境中建立的模型,Windows Sockets 2.0为套接字I/O包含了重叠范例,还包含了分散/聚集的能力。WSASend()、WSASendto()、WSARecv()、WSARecvFrom()都以应用程序缓冲区数组作为输入参数,可以用于执行分散/聚集方式的I/O操作。当应用程序传送的信息除了信息体还包含一个或多个固定长度的首部时,这种操作非常有用,发送之前不需要由应用程序将这些首部和数据连接到一个连续的缓冲区中,就可以直接将分散的多个缓冲区的数据发送出去,接收数据时与此类似。
6)服务质量控制。Windows Sockets 2.0为应用程序提供了协商所需的服务等级的能力,如带宽、延迟等。其他相关的QoS增强功能包括套接字分组、优先级、特定网络的QoS扩展机制等。
7)与Windows Sockets 1.1的兼容性。Windows Sockets 2.0与Windows Sockets 1.1在两个级别(源代码级和二进制级)上保持兼容,这最大化地方便了任意版本的Windows Sockets程序与任意版本的Windows Sockets实现之间的交互操作,同时将Windows Sockets程序的用户、网络协议栈以及服务的提供者因版本升级所带来的操作复杂性降到最低。
8)协议独立的多播和多点。应用程序可以发现传输层提供的多播或多点能力的类型,并以常规的方式使用它。
9)其他经常需要的扩展。例如,共享套接字、附条件接收、在连接建立/拆除时的数据交换、协议相关的扩展机制等。
Windows Sockets实现一般由两部分组成:开发组件和运行组件。
开发组件是供程序员开发Windows Sockets应用程序使用的,包括介绍Windows Sockets实现的文档、Windows Sockets应用程序接口(API)引入库和一些头文件。头文件winsock.h、winsock2.h对应于Windows Sockets 1.0和Windows Sockets 2.0,是Windows Sockets中重要的头文件,它们包括了Windows Sockets实现所定义的宏、常数值、数据结构和函数调用接口原型。
运行组件是Windows Sockets应用程序接口的动态链接库(DLL),应用程序在执行时通过装入它来实现网络通信功能。两个版本的动态链接库如表2-1所示。
表2-1 Windows Sockets版本中的动态链接库
使用动态链接库时,需要在程序编译前将对应的头文件引入源文件,以便编译环境可以找到相应函数和变量的声明,并在项目中引入静态链接库文件,以便在程序编译通过后,连接时可以找到套接字函数的执行地址。
以Windows Sockets 2.2为例,使用以下代码段引入头文件:
使用以下代码段引入静态链接库:
或者在开发环境中的项目菜单里增加对“ws2_32.lib”文件的引入,如图2-2所示。
图2-2 增加对“ws2_32.lib”文件的引入