16.1 引言
16.1.1 什么是客户端/服务器架构
什么是客户端/服务器架构?不同的人有不同的答案。这要看你问的是什么人,以及指的是软件系统还是硬件系统了。但是,有一点是共通的:服务器是一个软件或硬件,用于向一个或多个客户端(客户)提供所需要的“服务”。服务器存在的唯一目的就是等待客户的请求,给这些客户服务,然后再等待其他的请求。
另一方面,客户连上一个(预先已知的)服务器,提出自己的请求,发送必要的数据,然后就等待服务器的完成请求或说明失败原因的反馈。服务器不停地处理外来的请求,而客户一次只能提出一个服务的请求,等待结果。然后结束这个事务。客户之后也可以再提出其他的请求,只是,这个请求会被视为另一个不同的事务了。
图16-1展示了如今最常见的“客户端/服务器”结构。一个用户或客户端电脑通过因特网从服务器上取数据。这的确是一个客户端/服务器架构的系统,但还有更多类似的系统满足客户端/服务器架构。而且,客户端/服务器架构也可以像应用到软件上那样应用到计算机硬件上。
图 16-1 因特网上典型的客户端/服务器概念
1.硬件的客户端/服务器架构
打印(机)服务器是一个硬件服务器的例子。它们处理打印任务,并把任务发给相连的打印机(或其他打印设备)。这样的计算机一般是可以通过网络访问的,而且客户机器可以远程发送打印请求给它。
另一个硬件服务器的例子是文件服务器。它们一般拥有大量的存储空间,客户可以远程访问。客户端计算机可以把服务器的磁盘映射到自己本地,就像本地磁盘一样使用它们。其中,Sun公司的NetworkFile System (NFS)是使用最为广泛的网络文件系统之一。如果你事实上已经映射了一个网络上的磁盘,但你却不知道它到底是本地的还是网络的,那客户端/服务器系统就很好的完成了它们的工作。其目的就是要让用户使用起来感觉就像使用本地磁盘一样。“抽象”到“一般的磁盘访问”这一层面之后,所有的操作就都是一样的了,而让所有操作都一样的“实现”则要依靠各自的程序了。
2.软件客户端/服务器架构
软件服务器也是运行在某个硬件上的。但不像硬件服务器那样,有专门的设备,如打印机、磁盘等。软件服务器提供的服务主要是程序的运行、数据的发送与接收、合并、升级或其他的程序或数据的操作。
如今,最常用的软件服务器是Web服务器。一台机器里放一些网页或Web应用程序,然后启动服务。这样的服务器的任务就是接受客户端的请求,把网页发给客户端(如用户计算机上的浏览器),然后等待下一个客户端请求。这些服务启动后的目标就是“永远运行下去”。虽然它们不可能实现这样的目标,但只要没有关机或硬件出错等外力干扰,它们就能够运行非常长的一段时间。
数据库服务器是另一种软件服务器。它们接受客户端的保存或读取请求,完成请求,然后再等待其他的请求。它们也被设计为要能“永远”运行。
我们要讨论的最后一种软件服务器是窗口服务器。这些服务器几乎可以被认为是硬件服务器了。它们运行于一个有显示器的机器上。窗口客户端实际上是那些在运行时需要窗口环境的程序,它们一般叫做图形用户界面(GUI)程序。这些程序如果在一个DOS窗口或Unix的shell等没有窗口服务器的纯文本环境中运行,将无法启动。一旦窗口服务器可以使用时,那一切就正常了。
当世界有了网络,那这样的环境就开始变得更有趣了。一般情况下,窗口客户端的显示和窗口服务器的提供都在同一台电脑上。但在X Window之类的网络化的窗口环境中,你可以选择其他电脑的窗口服务器来做显示。即你可以在一台电脑上运行GUI程序,而在另一台电脑上显示它!
3.银行出纳是服务器吗
理解客户端/服务器架构的一个方法是,想象一个不吃不喝不睡觉的银行出纳,他依次向排成长龙的顾客们提供一个又一个的服务(图16-2)。有时,队伍可能很长,有时也可能没人。但顾客随时都可能出现。当然,在以前,是不可能有这样的出纳的。但现在的ATM机与这个模型很像。
图 16-2 图中的银行出纳“永远不停歇”地为客户提供服务
当然,出纳就是一个运行在无限循环里的服务器。每一个顾客就是一个想要得到服务的客户。顾客到了之后,就按先来先服务(first-come-first-served, FCFS)的原则得到服务。一个事务结束后,客户就离开了,而服务器则要么马上为下一个顾客服务,要么坐着等待下一个顾客的到来。
为什么这些概念那么重要?因为,这种执行的方式就是客户端/服务器架构的特点。现在你对此已经有了大体的认识,我们就可以把客户端/服务器架构模型应用到网络编程中。
出纳运行在一个接收请求,处理请求然后再处理其他请求或等待其他客户的无限循环中。客户有可能已经排起了长龙,也有可能根本就没有客户。但是,无论如何,服务器都不会结束工作。
16.1.2 客户端/服务器网络编程
在完成服务之前,服务器必需要先完成一些设置。先要创建一个通讯端点,让服务器能“监听”请求。你可以把我们的服务器比做一个公司的接待员或回答公司总线电话的话务员,一旦电话和设备安装完成,话务员也就位之后,服务就可以开始了。
在网络世界里,基本上也是这样——一旦通信端点创建好之后,我们在“监听”的服务器就可以进入它那等待和处理客户请求的无限循环中了。当然,我们也不能忘记在信纸上、杂志里、广告中印上公司的电话号码。否则,就没有人会打电话进来了!
同样地,服务器在准备好之后,也要通知潜在的客户,让它们知道服务器已经准备好处理服务了,否则没有人会提请求的。比方说,你建立了一个全新的网站。这个网站非常出色,非常的吸引人,非常的有用,是所有网站中最酷的一个。但如果你不把网站的网址或者说统一资源定位符(URL)广而告之的话,没有人会知道这个网站的存在的。这个网站也就永远不见天日了。对于公司总部的新电话也是这样,你不把电话公之于众,那就没有人会打电话进来。
现在,你对服务器如何工作已经有了一个很好的认识。你已经完成了最难的那一部分。客户端的编程相对服务器端来说就简单得多了。所有的客户只要创建一个通信端点,建立到服务器的连接。然后客户端就可以提出请求了。请求中,也可以包含必要的数据交互。一旦请求处理完成,客户端收到了结果,通信就结束了。