3.7.1 套接字接口的产生与发展

3.7.1 套接字接口的产生与发展

如前所述,网络上的两台主机进行通信时,需要使用网络协议栈。从应用程序实现的角度来看,在进行程序开发时,希望用一种简单的方式来与下层网络协议栈连接,而无须考虑其具体的工作过程,仅仅需要考虑应用层涉及的问题即可。那么如何能方便地使用协议栈进行通信呢?能不能在应用程序与网络协议栈之间提供一个方便的接口,从而方便网络应用程序的编写呢?UNIX操作系统的开发者们提出并实现一种套接字接口,全称是套接字应用程序编程接口(Socket API,Socket Application Programming Interface),解决了UNIX操作系统下应用层的网络通信问题,而后扩展到了Windows和Linux系统中并得到继承,成为迄今为止最常用、最重要的一类网络编程接口。

套接字应用程序编程接口(以下简称套接字接口或者套接字)是网络应用程序通过网络协议栈进行通信时所使用的接口,即应用进程与网络协议栈之间的接口。套接字接口在网络体系中的位置如图3-36所示。

图3-36 套接字与应用进程、网络协议栈之间的关系

从套接字所处的位置来讲,套接字上连应用进程,下连网络协议栈。套接字是对网络中不同主机上应用进程之间进行双向通信的端点的抽象。进行通信的两个应用进程只要分别连接到自己的套接字,就能方便地通过网络进行通信,既不用去管下层协议栈的工作过程,也不用去管复杂的网络结构。从组成上来说,它定义了应用程序与协议栈模块进行交互时可以使用的一组操作,给出了应用程序能够调用的一组过程,以及这些过程所需要的参数。每个过程完成一个与网络协议栈模块交互的基本操作。例如,一个过程用来建立通信连接,一个过程用来接收数据,一个过程用来发送数据,等等。应用程序通过使用这组过程完成与对端应用程序通信的建立、数据的收发和通信的终止。

那么,为什么把网络编程接口称为Socket编程接口呢?Socket的英文原意是插座、插孔的意思。我们可以参考电气插座和电话插座的情况。在供电网络中,电能有多种来源,如火电站、水电站、核电站,等等,而这些电能到达使用者的身边也经过了一系列诸如升压、高压远程传送、降压和分配等复杂的传输过程。但是对于电器用户来说,并不需要了解电网的工作过程,只需要将电器的插头连接到电气插座上即可。电话插座也是如此,人们在使用电话机时,只需要将电话线一端插在电话机上,另一端连接到电话插座上即可,而不需要了解电话网的工作原理。以上两种情况中,电气插座/电话插座都是电网/电话网面向用户的一个端点,只要连接上这个端点,就可以使用网络中的资源。

套接字接口在计算机网络中的位置与电气插座/电话插座在电网/电话网中的位置类似,它可以看成计算机网络面向用户的一个端点。

套接字的两种实现方式

要实现套接字编程接口,可以采用两种方式:一种是在操作系统的内核中增加相应的软件来实现,另一种是通过开发操作系统之外的函数库来实现。

在BSD UNIX(Berkeley Software Distribution UNIX)及源于它的操作系统中,套接字函数是操作系统本身的功能调用,是操作系统内核的一部分。由于套接字使用越来越广泛,其他操作系统的供应商(如Windows和Linux等)也纷纷决定将套接字编程接口加入他们的系统中。在许多情况下,为了不修改他们的基本操作系统,供应商们开发了套接字库(Socket Library)来提供套接字编程接口。也就是说,供应商开发了一套过程库,其中每个过程具有与UNIX套接字函数相同的名称与参数。套接字能够向没有本机套接字的计算机上的应用程序提供套接字接口。

从开发应用的程序员角度看,套接字库与操作系统内核中实现的套接字在语义上是相同的。程序调用套接字过程,不需要管它是由操作系统提供的还是由库函数提供的。这就带来了程序的可移植性,将程序从一台计算机移植到另一台具有不同操作系统的计算机上时,程序的源代码改动不大。只要用新的计算机上的套接字库重新编译后,就可以在新的计算机上执行。