网络应用(network application)是计算机网络之所以存在的理由。要是我们设想不出任何有用的网络应用,那就没有必要设计支持它们的网络协议了。不过,过去30年内已有不少人设计出大量精妙的网络应用。这些应用既包括从20世纪80年代流行起来的基于文本的经典应用,例如远程计算机访问、电子邮件、文件传送、新闻组、聊天等;也包括近些年来所谓的多媒体应用,例如Web、因特网电话、视频会议、音频/视频点播等。尽管网络应用品种繁多是有许多彼此交错的部件,其软件却几乎总处于核心地位。网络应用的软件分布于两个或以上的端系统(即主机)。例如,Web应用包括彼此通信的两部分软件:运行在用户的主机(PC机、MAC机、工作站等)中的浏览器软件,以及运行在Web服务器上的Web服务器软件。Telnet应用同样由分别运行于本地主机和远程主机中的两部分软件构成。至于多方视频会议,参与会议的每台主机上都运行着一部分软件。  用操作系统的行话来说,彼此通信的实际上不是软件部件(即程序)本身,而是进程。我们可以把进程看成是在端系统中运行着的程序。运行在同一个端系统上的进程彼此间通过使用进程间通信手段通信。进程间通信的具体规则由端系统的操作系统决定。本文不关心同一台主机内的进程间通信,而关心运行在不同主机(操作系统也可能不一样)的进程间的通信。运行在不同端系统上的进程通过网络交换消息彼此通信。发送进程创建消息并将之传入网络;接收进程收取这些消息,并可能发送消息作为响应,如下图所示。每个网络应用都有各自的应用层协议,它定义在进程间交流的消息的格式和顺序,以及在送出或收到消息时采取的行动。应用层是我们着手研究协议的好地方。我们已经熟悉依赖于协议的许多应用。这将给我们一种似曾相识的感觉,知道协议的目的所在,有助于我们了解以后学习传输层协议、网络层协议和数据链路层协议时会碰到的许多同样的问题。 应用层协议  把网络应用和应用层协议区分开来相当重要。应用层协议仅仅是网络应用的一部分,让我们看几个例子。Web是一个允许用户从Web服务器按要求取得“文档”的网络应用,web应用由许多部件构成,包括—个文档格式的标准(即超文本标记语言HTML)、Web浏览器软件、Web服务器软件(例如Apache、IIS服务器)、一个应用层协议。Web的应用层协议是超文本传送协议(HTTP),它定义如何在浏览器和web服务器之间传递消息。因此HTTP仅仅是Web应用的一部分。另一个例于是电子邮件应用。电子邮件应用同样由许多部件构成,包括安置用户信箱的邮件服务器、让用户阅读和创建电子邮件消息的邮件阅读器、一个定义电子邮件消息结构的标推、一组定义如何在服务器之间以及服务器和阅读器之间传递电子邮件消息并解释其特定部分(例如信头)的应用层协议。电于邮件应用的首要应用层协议是简单邮件传输协议(SMTP)。因此SMTP也仅仅是电子邮件应用的一部分。  我们已经指出,应用层协议定义运行在不同端系统上的应用程序进程如何彼此传递消息。具体地说,一个应用层协议定义:   ●所传递消息的类型,例如请求消息和响应消息。  ●各种消息类型的语法,也就是消息中的各个字段以及它们如何定界。  ●各个字段的语义,也就是各个字段中的信息的含义。  ●确定一个进程何时以及如何发出消息或响应所收到消息的规则。  有些应用层协议是在RFC文档中详细说明的,也就是说它们处于可免费获取的公众域。例如,HTTP就可以作为RFC获取。浏览器软件开发者只要遵循该RFC中定义的规则,其浏览器就可以从同样遵循这些规则的任何web服务器取得Web页面。然而,其他许多应用层协议却是专属的,有意不放在公众域中。例如,许多现有的因特网电话产品使用专属的应用层协议。   客户和服务器  一个网络应用协议通常拥有客户端(client side)和服务器端(server side)这两个对等的“端”或实体,它们分别对应运行客户程序的客户进程(简称客户)和运行服务器程序的服务器进程(简称服务器),如图2所示。处于一个端系统中的客户端与处于另一个端系统中的服务器端彼此通信。例如,web浏览器实现的是HTTP客户端,web服务器实现的是HTTP服务器端。在电子邮件应用中,发送邮件消息的邮件服务器扮演SMIP的客户端角色,接收邮件消息的邮件服务器扮演SMTP的服务器端角色。    对于许多应用来说,它们的客户端和服务器端可以同时实现在单台主机上。就以主机A和主机B之间的一个Telnet会话为例。如果这个Telnet会话是由主机A发起的(即主机A上有一个用户登录到了主机B),那么主机A运行的是该应用的客户端,主机B运行的是该应用的服务器端。相反,如果这个Telnet会话是由主机B发起的,那么主机B运行的是该应用的客户端。用于在两台主机之间传送文件的FTP提供了另外一个例子。两台主机之间一旦启动一个FTP会话,其中任何一台主机就可以在该会话结束之前向另一台主机传达文件。尽管如此,我们还是按照几乎所有网络应用的惯常情况,把发起会话的主机标为客户。另外,单台主机实际上可能同时作为某个给定应用的客户主机和服务器主机。例如,邮件服务器主机同时运行着SMlP客户端(用于发送邮件)和服务器端(用于接收邮件)。     进程间跨网络的通信  一个网络应用涉及两台不同主机中跨网络彼此通信的两个进程(当然,组播网络应用有可能涉及两台以上主机间的通信)。这两个进程通过经由各自的套接字(socket)发送和接收消息彼此通信。我们可以把套接字看作相应进程上的“门”:进程把消息发送到网络或从网络接收消息都得经过自身的套接字。当一个进程想给另一台主机中的另一个进程发送消息时,它就把该消息推出自家的门。该进程认定在这扇门的另一侧有一个传输设施会把这个消息传输到目的进程的门口。  图3展示了通过因特网彼此通信的两个进程间的套接字通信(本图假设底层的传输协议是TCP,不过UDP也可以同样使用)。可见套接字是单台主机内应用层和传输层之间的接口。套接字也用于指代应用程序和网络之间的应用程序接口(application program interface,简称API),因为它又是用于构造因特网中的网络应用程序的编程接口。应用程序开发人员可以完全控制套接字的应用层一侧,对于套接字的传输层一侧却几乎无能为力。对于传输层一侧他们只能控制:(1)传输协议的选择;(2)诸如最大缓冲区大小和最大片段大小等有限几个传输层参数的调整。一旦选定某个可用的传输协议,就使用由该协议提供的传输层服务来构造应用程序。    进程寻址  要让一台主机中的进程给另一台主机中的进程发送消息,发送进程必须能够识别接收进程。用于标识接收进程的信息有两个:(1)接收主机的主机名或主机地址,(2)在接收主机内部识别接收进程的标识符。  让我们先考虑主机地址。在因特网应用中,接收主机是用其IP地址(1P addresse)标识的。现在,我们知道IP地址是惟一标识每个端系统的一个32位二进制数值(更准确地说,IP地址惟一地标识将各台主机连接到因特网的网络接口),既然连接到公共因特网的任何端系统的IP地址必须全球惟一,IP地址的分配就必须仔细管理。ATM网络的寻址标准则不同于因特网。ITU—T已规定,在公共ATM网络中使用称为E.164地址(ITU1997)的类似电话号码的地址。  除了知道接收进程所在端系统的地址外,发送进程还得指定可让接收端系统把所传送消息定向到接收进程的信息。因特网中用于此目的的是接收进程的端口号(port number)。流行的应用层协议已被赋予特定的端口号。例如,使用HTTP协议的web服务器进程是以端口号80标识的,使用SMTP协议的邮件服务器是以端门号25标识的。RFC 1700列出了所有因特网标准协议众所周知的端口号。在开发新的网络应用程序时,必须赋予它一个新的端口号。   用户代理  再开始继续研究应用层协议之前,讨论一下用户代理(user agent)的概念也许有所裨益。用户代理是一个位于用户和网络应用之间的接口。例如,Web应用的用户代理是诸如Netscape Navigator和微软Internet Explore这样的浏览器。浏览器使得用严可以观看web页面、进行web冲浪、提供表单输入、与JAVA小应用程序交互,等等。浏览器还实现了HTTP协议的客户端。因此启动后的浏览器除给用户提供一个接口外,其进程还同时在经由一个套接字发送接收消息。另一个例子是关于电子邮件应用的。电子邮件应用的用户代理是“邮件阅读器”,它使得用户可以编写和阅读邮件消息。许多公司提供可运行在PC机、MAC机和工作站上的图形用户界面的邮件阅读器(例如Eudora,Netscape Messenger,Microsoft outlook)。运行在PC机上的邮件阅读器还实现了多个应用层协议的客户端,典型的有用于发送邮件的SMTP协议的客户端.以及用于检索邮件的某个邮件检索协议(例如POP3或IMAP)的客户端。     应用所需的服务  我们知道套接字是应用进程和传输协议之间的接口。发送端的应用进程通过这扇门送出消息。在门的另一侧,传输协议负责把这些消息跨网络传送到接收进程的门口。包括因特网在内的许多网络体系结构提供不止一个传输协议。在开发应用程序时,必须选择一个可用的传输协议。如何进行选择呢?最可能的情形是,先研究一下由可用的传输协议提供的服务,再选出其服务与应用程序的需求最为匹配的协议。   这种情形类似于在两个城市之间旅行时选择乘火车还是乘飞机。你只能选择其中一种运输方式,而每种方式提供的服务是不同的(例如火车提供市区载客服务.飞机提供更短的运输时间)。  网络应用可能要求传输协议提供什么样的服务呢?我们可以把网络应用的服务需求按以下3个尺度粗略地进行划分:可靠性、带宽、实时性。   可靠性  有些应用要求完全可靠地传送数据,也就是说不能有数据丢失,例如电子邮件、文件传送、远程主机访问、Web文档传送、财务应用等。丢失文件数据或财务交易数据的灾难性后果是可想而知的。另有一些丢失容忍应用(lose-tolerant application)可以容忍一定数量的数据丢失,例如实时音频/视频或仓储音频/视频等多媒体应用。在丢失容忍的多媒体应用中,数据的丢失可能会在播放出的音频/视频中引入短时脉冲干扰,不过不是至关紧要的损伤。数据丢失对于应用质量的影响以及实际可容忍的分组丢失量强烈依赖于应用本身及所用的编码方案。  带宽  有些应用必须以特定的持续速率传送数据才会有效。例如,如果某个因特网电话应用32Kbps的速率编码语音,那么它必须能够以同样的速率把数据发送到网络,再由网络递送到接收应用。如果得不到这个数量的带宽,应用就得以一个较低的速率编码,还得获取足以维持这个编码速率的带宽,否则只能放弃,因为对于这样的带宽敏感应用(bandwidth-sensitive application)来说,仅仅得到所需带宽的一半是没有用的。许多当前的多媒体应用对带宽敏感,不过将来的多媒体应用可能用上自适应编码技术,能够以与当前的可用带宽相匹配的速率编码。带宽敏感应用需要一个给定数量的带宽,而与之相对的是,弹性应用(elastic application)却可以根据临时可用量随多随少地使用带宽。电子邮件、文件传送、远程访问、web传送等都是弹性应用。当然带宽肯定越高越好。   实时性  诸如因特网电话、虚拟环境、远程电话会议、多方游戏等交互式实时应用要求数据的递送满足严格的定时限制,以此保证有效。这些应用中有许多要求端到端的延迟在数百毫秒或以下的数量级。例如,因特网电话中的长延迟往往导致交谈中不自然的停顿:在多方游戏或虚拟交互环境中,从采取行动到看见来自环境的响应之间的长延迟(譬如说在某个端到端连接结束时才看到来自另一个玩家的响应)将使得应用感觉起来不大现实。对于非实时应用来说,低延迟总比高延迟可取,不过它们不会对端到端延迟施加任何严格的限制。  下表汇总了一些流行的和新兴的因特网应用的可靠性、带宽和实时性需求。这仅仅是一些较为流行的因特网应用的若干关键需求的概要。我们的目的并不是提供网络应用需求的一个完整分类,而是简单地标识出可由此将网络应用需求归类的几个最重要的轴。     因特网(更一般地说,TCP网络)给应用程序提供两个传输协议:用户数据报协议(UserDatagram Protocol,UDP)和传输控制协议(Transaction Control Protocol,TCP)。当开发人员创建一个新的因特网应用时,他必须选择UDP或TCP这两个协议之一用于该应用。这两个协议给应用提供不同的服务模型。    由因特网传输协议提供的服务  TCP服务  TCP服务模型包括面向连接的服务和可靠的数据传输服务。调用TCP作为其传输协议的应用同时取得这两种服务。  面向连接的服务指的是客户端和服务器端的TCP在开始传输应用层消息之前,先交换传输层控制信息。这个所谓的握手过程警示客户和服务器,以便它们为来自对方的分组冲击做好准备。握手阶段结束之后,我们说这两个进程的套接字之间存在一个TCP连接(TCP connection)。这是一个全双工的连接,也就是说客户和服务器这两个进程可以同时通过该连接向对方发送消息。完成消息的发送后,应用进程必须告知TCP拆除这个连接。称这种服务为“面向连接”服务而不是“连接”服务(或者说“虚电路”服务)的理由在于,它两端的进程是以非常松散的方式连接的。  可靠的传输服务指的是彼此通信的进程可以依赖TCP无错地顺序递送所有数据。当其中任何一个应用进程把一个字节流传入套接字时,它可以指望TCP把同样的字节流递送到对方的套接字,中间不会有字节的丢失或重复。  TCP还包含一个拥塞控制机制,它是因特网的一种公益服务,其目的不在于让彼此通信的进程直接受益。TCP拥塞控制机制在网络变得拥塞时抑制发送进程(可以是客户,也可以是服务器)。确切地说,TCP拥塞控制试图把每个TCP连接限定在它所公平共享的网络带宽内。对于有最小带宽需求限制的实时音频和视频应用来说,抑制传输率会有很坏的后果。此外,实时应用可容忍数据丢失,不需要完全可靠的传输服务。由于这些原因,实时应用程序的开发人员通常设计成在UDP而不是TCP上运行他们的应用。  概述完TCP提供的服务后,我们说一下TCP没有提供的服务。首先,TCP不保证最小传输率。具体地说,TCP不允许发送进程以想要的任意速率发送;相反,发送速率受到TCP拥塞控制的调节,发送进程有可能被迫以一个较低的平均速率发送。其次,TCP不提供任何延迟保证。具体地说,发送进程把数据传入自己的TCP套接字之后,这个数据将最终到达其接收套接字,然而就该数据花多长时间到达那儿来说,TCP绝对不作保证。花几十秒甚至几分钟等待TCP从web服务器往Web浏览器递送一个消息(例如,其中含有一个HTML文件)也非罕见。总之,TCP保证递送全部数据,但对递送速率和所经历的延迟不加保证。  UDP服务  UDP是一个不提供非必要服务的轻量级传输协议,具有一个最简约的服务模型。UDP是无连接的,因此两个进程彼此通信之前没有握手过程。UDP提供不可靠的数据传输服务,也就是说当一个进程往自己的UDP套接字发出一个消息时,UDP不能保证这个消息会最终到达接收套接字。另外,就确实到达接收套接字的消息而言,它们的到达顺序也可能与发送顺序不一致。  UDP不包含拥塞控制机制,因此发送进程能够以任意速率往UDP套接字倾注数据。尽管不能保证所有的数据都到达接收套接字,但是仍会有相当比例的数据到达。实时应用程序的开发人员往往选择在UDP上运行他们的应用。与TCP类似,UTP也不提供任何延迟保证。  下表指出了一些流行的因特网应用所用的传输协议。我们看到,电子邮件、远程终端访问、web和文件传送都使用TCP。这些应用选择TCP的主要原因在于TCP提供可靠的数据传输服务,能够保证所有数据最终到达其目的地。我们还看到,因特网电话一般运行在UDP之上。一个因特网电话应用的两端都得以某个最小速率跨网络发送数据:与TCP相比,UDP更可能满足这个要求。另外,因特网电话应用可容忍数据丢失,因此并不需要由TCP提供的可靠数据传输服务。我们已经指出,TCP和UDP都不提供定时保证,这是不是意味着时间敏感的应用不能运行在当今的因特网上呢?其答案显然是否定的——时间敏感的应用已在因特网上存在好多年了。这些应用往往工作得相当出色,因为它们已被设计成能够尽最大程度地对付这种缺乏保证的服务。尽管如此,当延迟过大时(这在公共因特网中是常事),最聪明的设计也有其局限。总之,当今的因特网通常能够为时间敏感的应用提供满意的服务,但不能提供任何定时或带宽上的保证。  本文准备介绍的网络应用  因特网上,公众域和专属的应用层出不穷。我们不想百科全书式地罗列一大堆因特网应用,于是选了少数几个既重要且流行的应用集中讨论。我们将具体地讨论4个流行的应用:Web、文件传送、电子邮件、目录服务。我们首先讨论web,其原因不仅在于web是一个极其流行的应用,还在于它的应用层协议(即HTTP)相对简单,可用于阐明网络协议的许多关键因素。接下来讨论文件传送,因为其协议与HTTP恰好形成对照,使得我们可以强调一些额外因素。我们还讨论电子邮件,它是因特网中第一个高度流行的应用。应该看到,现代的电子邮件使用不止一个应用层协议。Web、文件传送和电于邮件有共同的服务需求:需要可靠的传输服务,没有特别的定时需求,能接受弹性带宽服务。TCP提供的服务完全满足这3个应用。域名系统(Domain Name System,DN5)是我们讨论的第4个应用,它为因特网提供目录服务。多数用户不会直接与DNS打交道;相反,他们通过其他应用(包括即将讨论的那3个应用)间接求助于DNS。DNS精妙地展示了可以怎样在因特网中实现分布式数据库。这4个即将讨论的应用对时间都不大敏感。