【2021/1/17修订】【梳理】计算机网络:自顶向下方法 第二章 应用层(docx)

计算机网络

知 识 梳 理

(第一版)

建议先修课程:数据结构。
配套教材:
Computer Networking - A Top Down Approach, 7th edition James F. Kurose, Keith W. Ross
参考书目:
1、计算机网络(第7版) 谢希仁 编著 高等教育出版社


链接:https://pan.baidu.com/s/1c8AGhR-RCZRy1_lWaDm69g
提取码:0000


二 应用层

声明
本章涉及到的网站www.3134.com、jasmine.org和www.oust.edu.cn均为针对举例而杜撰的假想网站。
本章发布后,经检验,部分网站存在有害信息。此情况纯属巧合。请大家珍爱生命,远离恶意网站。
2.1 网络应用背后的原理
现代网络应用程序常用的架构是:客户端-服务器(client-server,C-S)结构和对等(peer-to-peer,P2P)结构。
客户端-服务器体系结构中,长期在线的主机称为服务器,用于服务来自其它主机(客户端)的请求。譬如Web应用,始终在线的服务器为应用程序服务,请求来自客户端主机上的浏览器。当Web服务器从客户端收到对对象的请求时,它通过将请求的对象发送到客户端主机来响应。在C-S结构中,客户端不直接进行通信。C-S结构的另一个特点是服务器具有一个固定的、众所周知的IP地址(见后文)。由于服务器具有IP地址,且一般长期运行,因此客户端始终可以通过向服务器的IP地址发送数据包来与服务器联系。具有C-S体系结构的应用有:Web、FTP、Telnet和电子邮件等。
通常在C-S应用程序中,单服务器无法满足所有请求。如果一个社交网站只有一台服务器处理请求,那么很快就会不堪重负。因此,常使用数据中心。搜索引擎(例如Google,Bing,百度),互联网商务(Amazon,eBay,阿里巴巴……),基于Web的电子邮件(例如Gmail和Yahoo Mail),社交网络(比如,Facebook,Instagram,Twitter和微信)等,都使用若干个数据中心。数据中心可以具有数十万服务器,必须保证供电和维护。此外,服务提供商必须为从其数据中心支付互连和带宽成本。
在P2P架构中,对专用服务器的依赖很小(或没有)。相反,应用程序利用间歇连接在主机之间直接通信,这些主机称为对等方(peers)。对等方不属于服务提供商,而属于用户自己的PC,它们多位于家庭、大学和办公室。对等方无需通过专用服务器进行通信,因此该结构称为P2P。许多流量密集型应用,包括文件共享(如BitTorrent),P2P辅助的下载加速以及互联网电话和视频会议(例如Skype),都基于P2P架构。有些程序则具有C-S和P2P混合架构:许多即时通信程序中,服务器跟踪用户的IP地址,但是用户到用户的消息直接在用户主机之间发送,而不通过中间服务器。
P2P架构最引人注目的特性之一就是可扩展性(self-scalability)。例如,在P2P文件共享中,每个对等方都通过请求文件来产生工作量,但每个对等方还通过将文件分发给其它对等方来增加系统的服务容量。P2P成本低,因为通常无需大量的服务器及服务器带宽。但是,由于P2P应用程序高度去中心化,因此面临安全性、性能和可靠性方面的挑战。

网络应用程序由成对的通过网络相互发送消息的进程组成。例如,在Web应用程序中,客户端浏览器进程与Web服务器进程交换消息。在P2P文件共享系统中,文件从一个对等方的进程传输到另一个对等方的进程。对于每对通信进程,通常将一个称为客户端,另一个称为服务器。
客户端和服务器进程的确定方法是:在一对进程的通信会话中,启动通信(在会话开始时最初与另一个进程联系)的进程为客户端。等待联系以开始会话的进程是服务器。对于Web,浏览器进程是客户端,而Web服务器进程是服务器。对于P2P文件共享,一般是下载和上传文件的对等方分别标记为客户端、服务器。如果一个对等方请求向另一个对等方发送文件,则请求方为客户端,接收方为服务器。

大多数网络应用程序包括若干对通信进程,每对进程相互通信。进程间传送的任何消息都必须经过网络。进程通过称为套接字(socket)的软件接口收发消息。套接字是主机内应用层与运输层之间的接口,也属于应用程序编程接口(API),位于应用程序和网络之间。应用程序开发人员可以控制套接字的应用层一侧的所有内容,但几乎不能控制套接字的运输层一侧——在运输层仅有的控制权是:(1)选择传输协议;(2)可能允许修改运输层参数(例如最大缓冲区和最大段大小,见第3章)。一旦应用程序开发人员选择了传输协议(如果可选),就使用该协议提供的运输层服务来构建应用程序。

为了识别接收进程,需要指定两条信息:主机的地址、目标主机中接收进程的标识符。
在Internet中,主机通过IP地址进行唯一标识。除了知道目标主机地址,发送进程还必须确定主机中运行的接收进程(更具体地说,是接收套接字)。这是因为主机一般同时运行许多网络应用程序。目标端口号(port number)用于确定接收进程。常见应用已经被分配特定端口:Web服务器(HTTP)的端口号是80,邮件服务器进程(使用SMTP协议)的端口号是25,HTTPS的端口是443。所有Internet标准协议的端口号可以在www.iana.org上找到。

发送端通过套接字发送消息。在套接字的另一端,运输层协议负责将消息发送到接收进程的套接字。许多网络(包括Internet)提供多个运输层协议。开发应用时,必须选择其中一种。
运输层协议可以为调用该协议的应用程序提供哪些服务?我们分成四类:数据传输可靠性保证、吞吐量保证、延迟保证和安全性保证。

数据包可能会在网络中丢失:或溢出路由器的缓冲区,或在某些位损坏后被主机或路由器丢弃。对许多应用(电子邮件,文件传输,远程主机访问,Web文档传输和财务应用程序等),数据丢失可能会带来灾难性的后果。这时必须保证发送的数据被正确而完整地传递到另一端。如果协议提供了这种保证,则说它提供了可靠的数据传输。当传输协议提供此服务时,发送进程完全有把握数据将正确无误地到达。
运输层协议不提供可靠的数据传输时,某些数据可能永远不会到达接收进程。对于容错型应用程序来说,这是可以接受的。最典型的是多媒体应用:这类程序能忽略少量的影音数据丢失,代价是音视频出现一些小瑕疵。

两个进程的网络通信会话中,吞吐量是发送进程可以将比特向接收进程发出的速率。由于其它会话会共享带宽,因此吞吐量可能波动。运输层协议可以提供另一种服务:保证吞吐量。应用程序发出响应请求后,传输协议将确保该吞吐量。此服务适合许多应用程序。例如,如果Internet电话以32 kbps编码语音,则需要保证至少以该速率将数据传送到接收应用程序。如果传输协议不能提供此吞吐量,应用程序就要以更低的速率编码,或者拒绝继续语音。具有吞吐量要求的应用程序称为带宽敏感应用程序(bandwidth-sensitive application)。许多多媒体应用都对带宽敏感,尽管它们可能使用自适应编码技术以匹配当前可用吞吐量。
有的应用程序比较容易适应不同的吞吐量,例如电子邮件,文件传输和Web传输。当然,吞吐量越大越好。

运输层协议也可以提供时延保证。与吞吐量保证一样,延迟保证有多种形式。示例:发送方注入到套接字中的每一位在100 ms内到达接收者的套接字。这样的服务适合交互式实时应用程序,比如Internet电话、虚拟环境、远程会议和多人游戏,都要求严格的传输延迟。网络电话延迟过长会导致通话中出现不自然的停顿。在多人游戏或虚拟互动环境中,采取行动与看到响应的间隔很长,会导致真实感降低。对非实时应用,较低的延迟虽然也更好,但是不必要对端到端延迟严格保证。

传输协议可以为应用程序提供安全服务。例如,在发送主机中,传输协议对发送数据加密;在接收主机中,运输层协议在数据到达接收进程之前对其解密。即使数据在传输过程被截获,秘密性(confidentiality)也能保证。除了秘密性,传输协议还可以提供其它安全服务,包括数据完整性和端点身份验证。

下表给出了几个常用的网络应用对数据丢失、吞吐量和延迟的要求。

TCP服务模型包括面向连接的服务和可靠的数据传输服务。应用程序调用TCP作为传输协议时,从TCP获得这两个服务。
·面向连接的服务。在应用层报文开始传输之前,TCP使客户端和服务器相互交换运输层控制信息。这种握手(handshaking)过程向客户端和服务器发出提示,使它们为接收数据包做好准备。握手之后,两个进程的套接字之间建立了TCP连接。该连接是全双工(full-duplex)的,两个进程可以彼此同时发送消息。发送完毕后,必须断开连接。
·可靠的数据传输服务。一方可以依靠TCP将字节流传递到接收套接字,而不发生丢失或重复。
TCP还包括拥塞控制机制,这是一种考虑Internet的普遍利益而不是通信过程的直接利益的服务机制。当网络在发送方和接收方之间拥塞时,将限制客户端或服务器的发送速率。我们会在第3章看到,TCP拥塞控制还试图限制每个TCP连接,以确保公平的网络带宽分配。

TCP和UDP都不提供任何加密。如果发送过程将明文密码发送到套接字,则密码将在途经的所有链接上传播,并有可能被嗅探和发现。Internet社区已经开发出了针对TCP的增强功能——安全套接层(secure socket layer,SSL)。使用SSL的TCP不仅可以执行传统TCP的所有操作,还可以提供关键的进程间安全服务,包括加密、数据完整性和端点身份验证。必须强调,SSL不是与TCP和UDP同级的第三个Internet传输协议,而是在应用层实现的增强功能。如要使用SSL服务,则需在程序的客户端和服务器端都包含SSL代码(使用一些高度优化的库和类)。SSL具有自己的套接字API,它与传统的TCP套接字API相似。使用SSL时,发送过程将明文数据传递到SSL套接字;然后,发送主机中的SSL对数据加密,并将加密的数据传递到TCP套接字。在接收过程中,加密的数据通过Internet传输到TCP套接字。接收套接字将加密的数据传递给SSL,SSL对其解密。最后,SSL将明文数据通过其SSL套接字传递到接收过程。

UDP是一种简洁、轻便的传输协议,提供尽量少的服务。UDP是无连接的,两个进程通信之前无需握手。UDP提供不可靠的数据传输服务,不保证消息到达接收进程。此外,到达接收过程的消息可能是乱序的。
UDP不包含拥塞控制机制,因此发送方可以以任何速率将数据泵入下面的层(网络层)。由于中间链路的传输容量有限或拥塞,实际的端到端吞吐量往往低于此速率。

TCP提供了可靠的端到端数据传输;还可以使用SSL在应用层增强TCP,以提供安全服务。但是,之前的简短描述中,没有提到吞吐量或延迟保证——当今的Internet传输协议并不提供它们。但这并不意味着时间敏感应用程序(例如Internet电话)无法在当今的Internet中运行,因为它们被设计成能够最大程度地应对这种缺乏保证的情况。不过,当延迟过高或端到端吞吐量受限时,这些设计无法保证程序不受影响。总之,当今的Internet虽然可以使时间敏感型应用程序提供令人满意的服务,但不能提供任何延迟或吞吐量保证。
下面列举常用应用的传输协议。邮件、远程终端访问、Web和文件传输都使用TCP,主要是因为TCP提供了可靠的数据传输,从而确保所有数据都能到达目的地。Internet电话通常不受少量数据丢失的影响,但对最低速率有要求,因此Internet电话的开发人员通常更喜欢给程序使用UDP,从而避免了TCP的拥塞控制和数据包带来的开销。但许多防火墙阻止(大多数类型的)UDP通信,因此Internet电话常被设计为在UDP通信失败时改用TCP。

网络进程通过向套接字发送报文来相互通信。但是这些报文的结构如何?各个字段的含义是什么?何时发送?这些问题与应用层协议有关。应用层协议定义了不同终端上运行的应用程序进程如何相互传递报文。具体来说,它们定义了:
·交换的报文类型,例如请求报文和响应报文。
·不同类型报文的语法,例如报文中的字段以及如何描述这些字段。
·字段的语义,即字段中信息的含义。
·确定进程何时以及如何发送或响应报文。

某些应用层协议在RFC中指定。遵循HTTP RFC规则的浏览器能够从也遵循HTTP RFC规则的任何Web服务器中检索网页。许多应用层协议是专有的,在公共领域不可用。例如,Skype使用专有的应用层协议。
区分网络应用程序和应用层协议非常重要。应用层协议只是网络应用程序的一部分,定义的是应用进程间通信和交互的规则。例:Web是一个C-S结构的应用程序,允许用户从Web服务器获取文档(Document)。Web应用程序由许多组件组成,包括文档格式标准(HTML)、浏览器(例如Firefox和Microsoft Edge),Web服务器(例如Apache和Microsoft服务器)以及应用层协议。Web的应用层协议HTTP定义了浏览器和Web服务器之间交换的消息的格式和顺序。因此,HTTP只是Web应用程序的一部分。又比如,Internet电子邮件应用程序具有许多组件,包括容纳用户邮箱的邮件服务器;允许用户阅读和创建消息的邮件客户端(例:Outlook);定义了邮件结构的标准;以及定义服务器之间、服务器和客户端之间如何传递及解释消息头的应用层协议。邮件的主要应用层协议是SMTP(2.3节)。因此,SMTP只是电子邮件应用的一部分。
2.2 Web和HTTP
万维网(World Wide Web,WWW)并非某种特殊的计算机网络。万维网是一个大规模的、联机式的信息储藏所,是一种存储信息的方式。WWW也可简称Web。万维网能通过链接非常方便地从互联网上的一个站点访问另一个站点(也就是所谓的“链接到另一个站点”),从而获取丰富的信息。
WWW是由Tim Berners-Lee于1989年3月提出的。1989年夏,Tim成功开发出世界上第一台Web客户端和第一台Web服务器,并为他的发明正式定名WWW。为了让WWW快速促进世界的发展,Tim放弃申请关于WWW的一切专利。在2012年伦敦奥运会开幕式上,Tim Berners-Lee爵士亮相,并在一台NeXT计算机上打出了“This is for Everyone”字样,言外之意,互联网献给所有人。2017年,他因“发明万维网、第一个浏览器和使万维网得以扩展的基本协议和算法”而获得2016年度的图灵奖。

万维网是分布式超媒体(hypermedia)系统,它是超文本(hypertext)系统的扩充。
超文本,是指包含指向其它文档的链接的文本。一个超文本可以由分布在互连网上的多个信息源链接成。超文本是WWW的基础。超媒体与超文本的区别是文档内容不同:超文本文档仅包含文本信息;超媒体文档包含文本信息、图形、图像、声音、动画,甚至活动视频图像。

超文本传输协议(HyperText Transfer Protocol,HTTP)是Web的应用层协议,也是Web的核心。HTTP在两个程序中实现:客户端程序和服务器程序。在不同的终端上执行的客户端程序和服务器程序通过交换HTTP报文相互通信。HTTP定义了这些报文的结构以及客户端和服务器如何交换报文。在详细解释HTTP之前,先回顾一些Web术语。

Web页面(也称为文档)由对象组成。对象(object)就是一个文件(例如HTML文件,PNG图像或视频剪辑),可以通过单个URL(uniform resource locator,通用资源定位符)进行定位。大多数网页由基本HTML文件(base HTML file)和几个引用的对象组成。例:如果一个网页包含HTML文本和五个PNG图像,则该网页具有六个对象。基本HTML文件使用对象的URL引用页面中的其它对象。关于HTML的介绍参见本节后文。
URL包含两部分:存储该对象的服务器的主机名(hostname)和该对象的路径名。例如:
https://cs.oust.edu.cn/courses/nlp/intro.pdf
的主机名是cs.oust.edu.cn,路径名是/courses/nlp/intro.pdf。因为Web浏览器实现了HTTP的客户端,所以浏览器和客户端在这里是同义词。Web服务器实现HTTP的服务器端,存储了Web对象,每个对象都可以通过URL寻址。HTTPS是使用SSL的HTTP,将在8.6节学习SSL。
URL的一般格式是:
<协议>://<主机>:<端口>/<路径>
协议部分常见的有http、ftp和https。现在的浏览器为了方便用户,在输入URL时,可以把最前面的http://和主机名最前面的“www”省略,然后浏览器替用户把省略的字符添上。

HTTP的URL的一般形式是:
http://<主机>:<端口>/<路径>
HTTP的默认端口号是80,通常可省略。若再省略文件的<路径>项,则URL就指向互联网上的某个主页(homepage)。主页通常是:
(1) 一个WWW服务器的最高级别的页面。
(2) 某一个组织或部门的一个定制的页面或目录。从这样的页面可链接到互联网上的与本组织或部门有关的其它站点。
(3) 由某人自己设计的描述他本人情况的WWW页面。

HTTP定义Web客户端如何从Web服务器请求页面,以及服务器如何将网页传输到客户端。当用户请求Web页面时(例如,单击超链接(hyperlink)),浏览器会将页面中该对象的HTTP请求报文发送到服务器。服务器接收请求并使用包含该对象的HTTP响应报文进行响应。
HTTP使用TCP作为基础传输协议而不是UDP。HTTP协议本身是无连接的。
HTTP客户端首先启动与服务器的TCP连接。建立连接后,浏览器和服务器进程将通过其套接字接口访问TCP。客户端将HTTP请求报文发送到其套接字接口,并从其套接字接口接收HTTP响应报文。同样,HTTP服务器从其套接字接口接收请求报文并发送响应报文。客户端将报文发送到其套接字接口后,该报文就不再由客户端而由TCP控制。回想2.1节,TCP为HTTP提供了可靠的数据传输服务。这意味着客户端发送的每份HTTP请求报文最终都会完整地到达服务器;同样,服务器发送的每份HTTP响应报文最终都会完整地到达客户端。在这里,分层体系结构带来了一个巨大优势:HTTP不必担心数据丢失,也不必考虑TCP如何恢复丢失的数据或对数据重新排序。这些是TCP和低层协议的工作。
HTTP是面向事务的(transaction-oriented)应用层协议。事务(transaction)这里指一系列不可分割的信息交换,也就是说,要么所有的信息交换都完成,要么一次交换都不进行。

注意:服务器不存储有关客户端的任何状态信息。如果同一个客户端频繁请求相同的对象,在不被识别为恶意请求的情形下,服务器不会只返回已经传输过此对象的提示,而是将重新发送该对象。HTTP服务器不保留有关客户端的信息,所以HTTP被称为无状态协议(stateless protocol)。
Web使用C-S结构。如2.1节所述,Web服务器长期在线,IP地址一般固定,可以为几百万个浏览器的请求提供服务。

对于非持久连接(non-persistent connection),我们来看一看将网页从服务器传输到客户端的步骤。假设该页面包含一个基本HTML文件和10个PNG图像,基本HTML文件的URL是
https://cs.oust.edu.cn/nlp/index.htm
传输的过程是:
1、HTTP客户端进程启动到服务器cs.oust.edu.cn的TCP连接(DNS解析完毕后),端口为80(HTTP的默认端口号)。客户端和服务器将各有一个与建立的TCP连接关联的套接字。
2、HTTP客户端通过其套接字向服务器发送HTTP请求报文。请求报文包含路径名/nlp/index.htm。
3、HTTP服务器进程通过其套接字接收请求报文,从其存储器(RAM或磁盘)中检索对象/nlp/index.htm,将对象封装在HTTP响应报文中,然后通过其套接字将响应报文发送给客户端。
4、HTTP服务器进程告诉TCP关闭TCP连接(TCP直到确定客户端已经完整接收到响应报文后,才真正终止连接)。
5、HTTP客户端收到响应报文。TCP连接终止。报文指示了封装的对象是HTML文件。客户端从响应报文中提取文件,检查HTML文件,并找到对10个PNG对象的引用。
6、对每个引用的PNG对象重复前四个步骤。

浏览器接收到网页后,显示页面给用户。不同的浏览器可能以不同的方式解释(即显示)网页。HTTP与客户端如何解释网页无关,HTTP规范仅定义了客户端HTTP程序和服务器HTTP程序之间的通信协议。
以上步骤解释了非持久连接:每个TCP连接在服务器发送相应的对象后关闭,而不为其它对象保留。每个TCP连接恰好传输一个请求报文和一个响应报文。在此示例中,共生成了11个TCP连接。
上述步骤没有说明客户端是通过10个串行TCP连接获得了10个PNG,还是某些PNG是通过并行TCP连接获得的。实际上,用户可以在浏览器中设置并行度。大多数浏览器默认最多打开5到10个并行TCP连接,并且每个连接都处理一个请求-响应事务。如果用户愿意,可以将最大并行连接数设置为1。在这种情况下,将串行建立10个连接。
并行连接的使用缩短了响应时间。

在继续之前,估计一下从客户端请求基本HTML文件到客户端接收整个文件所花费的时间。
往返时间(RTT),即小数据包从客户端到服务器再返回到客户端所花费的时间,包括数据包传播延迟,中间路由器和交换机中的数据包排队延迟,以及数据包处理延迟。这些延迟在1.4节进行了讨论。用户单击超链接时,浏览器启动与Web服务器之间的TCP连接。这涉及三次握手(3-way handshake):客户端向服务器发送一个小的TCP段;服务器以一个小的TCP段进行确认和响应;最后,客户端向服务器确认。三次握手的前两个部分计一次RTT。完成前两部分后,客户端将HTTP请求报文与三向握手的第三部分(确认)一起发送到TCP连接中。一旦请求报文到达服务器,服务器就将HTML文件发送到TCP连接。这个HTTP请求/响应再计一个RTT。因此,总响应时间约为两个RTT加上HTML文件所在的服务器上耗费的检索、服务器间传输等的时间。

非持久连接有一些缺点。首先,必须为每个请求的对象建立并维护一个全新的连接。对每一个连接都必须分配TCP缓冲区,并且必须在客户端和服务器中都保留TCP变量。这可能会给Web服务器带来沉重负担。其次,每个对象会带来两个RTT的传递延迟:一个RTT用于建立TCP连接,一个RTT用于请求和接收对象。
有了HTTP 1.1持久连接(persistent connection),服务器在发送响应后保持TCP连接。可以通过该连接发送同一客户端和服务器之间的后续请求和响应。具体而言,整个Web页面(上例包含基本HTML文件和10个图像)可以通过单个持久TCP连接发送。
此外,还可以通过单个持久TCP连接将同一服务器上的多个Web页面从服务器发送到同一客户端。这些对对象的请求可以紧密发出,而无需一直等待答复(流水线化)。通常,HTTP服务器在一定时间(可更改)未通过该连接通信时会关闭连接。当服务器接收到高密度的请求时,它将高密度地发送对象。HTTP默认使用带有流水线的持久连接。HTTP / 2(HTTP 2.0)建立在HTTP 1.1上,它允许在同一连接中对多个请求和响应进行交织,并提供了一种在该连接中对HTTP报文请求和响应分配优先级的机制。

HTTP报文有两种:请求报文和响应报文。下面是一份典型的HTTP请求报文:
GET /video/index.html HTTP/2.0
Host: www.3134.com
Connection: close
User-agent: Mozilla/5.0
Accept-language: zh-CN
首先,报文是用普通的ASCII文本编写的,所以可以直接阅读。其次,该报文由五行组成,每行后跟回车符和(或)换行符(Windows:CRLF,Linux:LF,Mac:CR),包括最后一行。HTTP请求报文有数行。第一行和随后的若干行分别称为请求行(request line)和报头行(header lines,首部行)。请求行包含三个字段:方法字段,URL字段和HTTP版本字段。方法字段可以是:GET,POST,HEAD,PUT和DELETE。多数HTTP请求使用GET方法。当浏览器请求一个对象,且在URL字段中标识了所请求的对象时,使用GET。在此示例中,浏览器正请求/video/index.html,使用HTTP / 2.0。
这个例子中,报头行Host: www.3134.com指定对象所在的主机。您可能会认为此报头行是不必要的,因为已经有到主机的TCP连接。但Web代理缓存需要主机报头行提供的信息(见下文)。通过添加Connection: close报头行,浏览器告诉服务器它不想建立持久连接,希望服务器在发送请求的对象后关闭连接。User-agent:报头行指定用户代理(User Agent,UA)。UA是代表使用者行为的软件代理程序所提供的对自己的一个标识符,在这里是向服务器发出请求的浏览器类型。这里的UA是Firefox浏览器Mozilla / 5.0。该报头行允许服务器将同一对象的不同版本发送给不同类型的UA(每个版本可以使用相同的URL寻址),典型的例子就是网站的桌面版和移动版。最后,Accept-language:报头指示用户希望接收对象的中文版本。如果服务器上存在该对象,则发送之;否则,服务器发送默认版本。Accept-language:报头只是HTTP中可用的许多内容协商报头之一。
报头可以有好几行,但也可以不使用。

请求报文的一般格式如上图。在报头行之后,有一个“实体本体”(entity body)。实体本体在请求报文中一般不使用,在响应报文中也可以不使用。实体本体在使用GET方法时为空,但在使用POST方法时不为空。当用户填写表单时(例如,向搜索引擎提供搜索词),HTTP客户端经常使用POST方法。如果方法字段为POST,则实体包含用户在表单字段中输入的内容。
包含表单的请求不一定使用POST方法。相反,HTML表单通常使用GET方法,并将输入的数据(在表单字段中)包括在请求的URL中。例如,如果表单使用GET方法,具有两个字段,分别输入spider-man和trailer,则URL的结构将类似于:www.3134.com/video/search?spider-man&trailer。这种扩展URL十分常见。
HEAD方法类似于GET方法。当服务器接收到带有HEAD方法的请求时,它将以HTTP报文进行响应,但会保留所请求的对象。开发人员常使用HEAD方法进行调试。PUT方法通常与Web发布工具结合使用。它允许用户将对象上传到特定Web服务器上的特定路径(目录)。需要将对象上载到Web服务器的应用程序也使用PUT方法。DELETE方法允许用户或应用程序删除Web服务器上的对象。

对HTTP请求报文,服务器可能会给出这样的响应报文:
HTTP/2.0 200 OK
Connection: close
Date: Sun, 11 Oct 2020 22:54:43 GMT
Server: Apache/2.4.44 (Debian)
Last-Modified: Sun, 11 Oct 2020 15:11:03 GMT
Content-Length: 1919810
Content-Type: text/html

(data data data data data …)
此回复报文包含三个部分:初始状态行(status line),6行报头行,然后是实体本体(主体)。实体主体是报文的基础,它包含所请求的对象本身。状态行具有三个字段:协议版本字段,状态代码和相应的状态报文。在此示例中,状态行指示服务器正在使用HTTP / 2.0,并且一切正常(已找到并正在发送请求的对象)。
现在看报头行。服务器使用Connection: close告诉客户端,将在发送报文后关闭TCP连接。Date:报头行指示服务器创建和发送HTTP响应的日期时间。注意,这不是创建或最后修改对象的时间,而是服务器从其文件系统检索对象,将对象插入响应报文并发送响应报文的时间。Server:报头行指示该报文是由Apache Web服务器生成的;它类似于HTTP请求报文中的User-agent:报头行。Last-Modified:报头行指示创建或最后修改对象的时间和日期。该标头对于本地客户端和网络高速缓存服务器中的对象缓存至关重要。Content-Length:报头行指示要发送的对象中的字节数。 Content-Type:报头行表示实体主体中的对象是HTML文本(对象类型由Content-Type:报头而不是文件扩展名正式表示)。

现在给出响应报文的一般格式,如上图所示。状态代码和相关的短语表示请求的结果。常见的状态代码及其短语包括:
200 OK:请求成功,并在响应中返回信息。
301 Moved Permanently:请求的对象已被永久移动;新的URL在响应报文的Location:报头行中指定。客户端软件将自动检索新的URL。
400 Bad Request:这是通用错误代码,指示服务器无法理解该请求。
404 Not Found:此服务器上不存在请求的文档。
505 HTTP Version Not Supported:服务器不支持所请求的HTTP协议版本。
概括地说,状态代码有5大类:
lxx表示通知信息,如请求收到了或正在进行处理。
2xx表示成功,如接受或知道了。
3xx表示重定向,如要完成请求还必须采取进一步的行动。
4xx表示客户的差错,如请求中有错误的语法或不能完成。
5xx表示服务器的差错,如服务器失效无法完成请求。

如何查看真实的HTTP响应报文?首先Telnet到指定的Web服务器。然后为服务器上存储的某个对象键入单行请求报文。 例如,如果您有权访问命令提示符,请键入:
telnet gaia.cs.umass.edu 80
GET /kurose_ross/interactive/index.php HTTP/1.1
Host: gaia.cs.umass.edu
(在最后一行键入后,按回车键两次)这将打开与主机gaia.cs.umass.edu的端口80的TCP连接,然后发送HTTP请求报文。您应该会看到一份响应报文,其中包含针对该教科书的作业问题的基本HTML文件。如果您只想查看HTTP报文行而不接收对象本身,则将GET替换为HEAD。
HTTP规范定义了许多报头行,这些报头行可以由浏览器,Web服务器和网络缓存服务器插入。浏览器将根据浏览器类型和版本生成报头行(例如,HTTP / 1.0浏览器将不生成任何1.1报头行),浏览器的用户配置(例如,首选语言)以及浏览器当前是否具有对象的缓存版本(可能已过期)构造报头行。Web服务器的行为类似:有不同的产品,版本和配置,所有这些都会影响响应报文中包含哪些报头行。

上面我们提到,HTTP服务器是无状态的。这简化了服务器设计,并允许工程师开发可处理同时维持大量TCP连接的高性能Web服务器。但是,由于服务器需要限制用户权限,或根据用户身份提供内容,因此网站通常希望标识用户。为此,HTTP使用cookie。Cookie允许网站跟踪用户。当今大多数主要的商业网站都使用cookie。
cookie具有四部分:(1)HTTP响应报文中的cookie报头行;(2)HTTP请求报文中的cookie报头行;(3)保留在用户的最终系统,并由用户的浏览器进行管理的cookie文件;(4)网站上的后端数据库。

我们通过一个示例演示cookie的工作原理。假设Susan总是从家用PC访问Web,第一次访问Amazon.com,已访问过eBay。当请求进入Amazon Web服务器时,服务器将创建一个唯一的标识号,并在后端数据库中创建一个由该标识号索引的条目。然后,Amazon Web服务器响应Susan的浏览器,在HTTP响应中包括Set-cookie:报头,其中包含标识号。例如,报头行可能是:
Set-cookie: 31d4d96e407aad42
Susan的浏览器收到HTTP响应报文时,会读取到Set-cookie:报头。然后浏览器将一行添加到它管理的特殊cookie文件。该行包括服务器的主机名和Set-cookie:报头中的标识号。请注意,由于Susan过去曾访问过该站点,因此cookie文件已经具有eBay条目。随着Susan继续浏览Amazon网站,每次她请求一个网页时,她的浏览器都会查询她的cookie文件,提取该站点的标识号,并将包含标识号的cookie报头行放在HTTP请求中。具体来说,她对Amazon服务器的每个HTTP请求都包含报头行:
Cookie: 31d4d96e407aad42
通过这种方式,亚马逊服务器可以记录Susan在亚马逊站点上的活动。Amazon未必知道Susan的真名,但知道用户31d4d96e407aad42以什么顺序、在什么时间访问了哪些页面。Amazon使用cookie实现购物车服务——维护苏珊所有预定购买的清单,以便她日后可以为它们一同付款。

如果Susan日后返回亚马逊网站,则她的浏览器将继续在请求报文中添加报头行:
Cookie: 31d4d96e407aad42
亚马逊还根据她访问过的网页推荐产品。如果Susan也在亚马逊注册(提供全名、邮件地址、邮政地址和信用卡信息等),那么Amazon可以将该信息写入到数据库,从而将Susan的姓名与ID以及过去曾在该网站访问过的内容关联。这就是Amazon和其他电商网站提供“一键式购物”的方式:Susan在后续购买商品时,无需重新输入姓名,信用卡号或地址。
Cookie可以用来识别用户。用户首次访问站点时,可以提供用户标识(可能是他或她的名字)。在后续会话期间,浏览器将cookie报头传递给服务器,从而为服务器标识用户。因此,可使用cookie在无状态HTTP之上创建用户会话层。例如,当用户登录基于Web的电子邮件应用程序(例如Hotmail)时,浏览器将cookie信息发送到服务器,从而允许服务器在用户与应用程序的整个会话过程中识别用户。
Cookie之所以引起争议,是因为它们也可以被视为侵犯隐私。结合Cookie和用户提供的帐户信息,网站可以了解很多有关用户的信息,并可能将该信息出售给第三方。Cookie Central包含有关Cookie争议的广泛信息。

Web缓存(Web cache),也称为代理服务器(proxy server),是代替原始Web服务器满足HTTP请求的网络实体。Web缓存具有自己的存储,在存储中保留最近请求的对象的副本。可以配置用户的浏览器,以便每个对对象的浏览器请求都首先定向到Web缓存。浏览器请求对象时,将会发生下列事件:
1、浏览器建立到Web缓存的TCP连接,并将对该对象的HTTP请求发送到Web缓存。
2、Web缓存检查服务器上是否具有对象副本。若是,则将HTTP响应报文中的对象返回到客户端浏览器。
3、如果Web缓存中没有该对象,则Web缓存将打开与原始服务器的TCP连接。然后,Web缓存将对对象的HTTP请求发送到缓存到服务器的TCP连接中。收到此请求后,原始服务器将对象发送到Web缓存的HTTP响应中。
4、当Web缓存接收到对象时,它将副本存储在其本地存储中,并在HTTP响应报文中将副本发送到客户端浏览器(通过客户端浏览器和Web缓存之间的现有TCP连接)。
除了专门的服务器以外,用户自己的计算机也可以进行缓存。

缓存同时是服务器和客户端。当它接收来自浏览器的请求并将响应发送到浏览器时,它是服务器。当它向原始服务器发送请求并从其接收响应时,它是一个客户端。
通常,Web缓存由ISP购买和安装。例如,大学可能会在校园网络上安装缓存,并配置所有校园浏览器以指向该缓存。大型居民ISP(如Comcast)可能会在其网络中安装一个或多个缓存,并预先配置浏览器以指向已安装的缓存。
Web缓存可以大大减少客户端请求的响应时间,尤其是客户端和原始服务器之间的带宽远小于客户端和缓存之间的带宽时。如果客户端和缓存之间存在高速连接(通常如此),并且缓存具有请求的对象,则缓存将能够快速将对象传递给客户端。另外,Web缓存可以大大减少机构访问Internet的流量。这使机构(例如公司或大学)不必尽快升级带宽,从而降低成本。此外,Web缓存减少了整个Internet上的Web流量,提高了所有应用程序的性能。

尽管缓存可以减少用户感知的响应时间,但它带来了一个新问题:缓存的对象副本可能不是最新的。换句话说,自从副本缓存以来,Web服务器中的对象可能已被修改。幸运的是,HTTP具有允许高速缓存验证其对象是否最新的机制。该机制称为条件GET(conditional GET)。
如果:(1)请求报文使用GET方法;(2)请求报文包含If-Modified-Since:报头行,那么该HTTP请求报文就是所谓的条件GET报文。
来看一个例子。首先,浏览器发出请求,代理缓存将请求报文发送到Web服务器:
GET /user/andybayerroswell/profile/avatar.png HTTP/2.0
Host: www.3134.com
其次,Web服务器发送包含请求对象的响应报文:
HTTP/2.0 200 OK
Date: Sat, 11 Oct 2020 23:15:15
Server: Apache/2.4.44 (Debian)
Last-Modified: Wed, 9 Sep 2020 09:23:24
Content-Type: image/png

(data data data data data …)
缓存将对象转发到发出请求的浏览器,也将对象缓存,并存储对象的修改日期。日后,另一浏览器通过缓存请求相同的对象,而该对象仍在缓存中。由于此对象可能已在过去一周在Web服务器上进行了修改,因此缓存通过发出条件GET来执行最新检查。具体来说,缓存发送:
GET /user/andybayerroswell/profile/avatar.png HTTP/2.0
Host: www.3134.com
If-modified-since: Wed, 9 Sep 2020 09:23:24
本例中,If-modified-since:报头行的值与服务器一周前发送的Last-Modified:报头行的值完全相同。该条件GET告诉服务器:仅在指定日期以来修改了该对象时,才发送该对象。现在,自2020年9月9日09:23:24以来未修改该对象。然后,Web服务器将响应报文发送到缓存:
HTTP/2.0 304 Not Modified
Date: Sat, 11 Oct 2020 23:15:15
Server: Apache/2.4.44 (Debian)

(empty entity body)
为响应条件GET,Web服务器仍发送响应报文,但报文中不包括请求的对象,因为这只会浪费带宽并增加响应时间,尤其是对象较大的情况下。最后一条响应报文在状态行中显示304 Not Modified,它告诉缓存可以将对象的(代理缓存)缓存副本转发给请求的浏览器。

要使任何一台计算机都能显示出任何一台WWW服务器上的页面,就必须解决页面制作的标准化问题。超文本标记语言HTML(HyperText Markup Language)就是一种制作万维网页面的标准语言,它消除了不同计算机之间信息交流的障碍。但请注意,HTML并不是应用层协议,它只是WWW浏览器使用的一种语言。由于HTML非常易于掌握且实施简单,因此它很快就成为WWW的重要基础。官方的HTML标准由WWW联盟W3C(WWW Consortium)负责制定。HTML在1993年问世后,就不断在更新。现在最新的版本是HTML 5.0 (2014年9月发布),新的版本增加了在网页中嵌入音频、视频以及交互式文档等功能。现在一些主流的浏览器都支持HTML 5.0。
HTML定义了许多用于排版的命令,即标签(tag)。例如,表示后面开始用斜体字排版,而则表示斜体字排版到此结束。HTML把各种标签嵌入到WWW页面中,就构成HTML文档。HTML文档是一种可以用任何文本编辑器创建的ASCII文件。但应注意,仅当HTML文档是以.html或.htm为后缀时,浏览器才对这样的HTML文档的各种标签进行解释。如果HTML文档改为以.txt为其后缀,则HTML解释程序就不对标签进行解释,而浏览器只能看见原来的文本文件。
并非所有的浏览器都支持所有的HTML标签。若浏览器不支持某HTML标签,则它将忽略此标签,但在一对不能识别的标签之间的文本仍然会被显示出来。
篇幅所限,这里不介绍HTML的具体语法。

XML(Extensible Markup Language),即可扩展标记语言,它和HTML很相似。但XML的设计宗旨是传输数据而不是显示数据(HTML是为了在浏览器上显示数据)。更具体些,XML用于标记电子文件,使其具有结构性的标记语言,可用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML是一种简单、平台无关、广泛采用的标准。XML相对于HTML的优点是:它将用户界面(UI)与结构化数据分隔开来。这种数据与显示的分离使得集成来自不同源的数据成为可能。客户信息、订单、研究结果、账单付款、病历、目录数据及其他信息都可以转换为XML。XML不是要替换HTML,而是对HTML的补充。XML标记由文档的作者定义,并且是无限制的。HTML标记则是预定义的;HTML作者只能使用当前HTML标准所支持的标记。
另一种语言XHTML(Extensible HTML)即可扩展超文本标记语言,它与HTML 4.01几乎是相同的。但XHTML是更严格的HTML版本,也是一个W3C标准(2000年1月制定),是作为一种XML应用被重新定义的HTML,并将逐渐取代HTML。所有新的浏览器都支持XHTML。

还有一种语言CSS(Cascading Style Sheets)是层叠样式表,它是一种样式表语言,用于为HTML文档定义布局。CSS与HTML的区别就是:HTML用于结构化内容,而CSS则用于格式化结构化的内容。例如,在浏览器上显示的字体、颜色、边距、高度、宽度、背景图像等方面,都能够给出精确的规定。现在所有的浏览器都支持CSS。

上面的文档只是万维网文档中最基本的一种,即静态文档(static document)。静态文档在文档创作完毕后就存放在WWW服务器中,在被用户浏览的过程中,内容不会改变,因此每次读取静态文档都返回相同结果。
静态文档的最大优点是简单。由于HTML是一种排版语言,因此静态文档可以由不懂程序设计的人员来创建。但静态文档不够灵活。当信息变化时,文档的作者要手工修改文档。可见,变化频繁的文档不适于做成静态文档。
动态文档(dynamic document)的内容是在浏览器访问WWW服务器时才由应用程序动态创建的。浏览器请求到达时,服务器要运行另一个应用程序,并把控制转移到此应用程序。接着,该应用程序对浏览器发来的数据进行处理,并输出HTTP格式的文档,该输出作为对浏览器的响应。由于这些响应都是临时生成的,因此用户看到的内容是不断变化的。动态文档的主要优点是具有报告当前最新信息(如:股市行情、天气预报或民航售票情况)的能力。但动态文档的创建难度比静态文档高,因为动态文档的开发不是直接编写文档本身,而是编写用于生成文档的应用程序,这就要求动态文档的开发人员必须会编程,而所编写的程序还要通过大范围的测试,以保证输入的有效性。
动态文档和静态文档之间的主要差别体现在服务器一端:主要是文档内容的生成方法不同。而从浏览器的角度看,这两种文档并没有区别。动态文档和静态文档的内容都遵循HTML所规定的格式,浏览器仅根据在屏幕上看到的内容无法判定服务器送来的是哪一种文档,只有文档的开发者才知道。

通用网关接口(Common Gateway Interface,CGI)是一种标准,它定义了动态文档应如何创建,输入数据应如何提供给应用程序,以及输出结果应如何使用。在万维网服务器中新增加的应用程序叫做CGI程序。
CGI程序的正式名称是CGI脚本(script)。脚本是一个程序,它先被解释器解释而不是由CPU直接执行。有一些语言专门作为脚本语言(script language),如Perl、REXX(在IBM主机上使用)、JavaScript、PHP、Tcl/Tk等。脚本也可用一些常用的语言写出,如C,C++等。脚本语言容易上手,开发耗时短,这对一些有限功能的小程序是很合适的。但脚本运行起来通常比编译程序要慢。脚本不一定是一个独立的程序,它可以是一个动态装入的库,甚至是服务器的一个子程序。
CGI程序又称为cgi-bin脚本,这是因为在许多WWW服务器上,为便于找到CGI程序,就将它们放在/cgi-bin的目录下。

随着HTTP和浏览器的发展,动态文档已明显不能满足发展的需要。这是因为:动态文档一旦建立,它所包含的信息内容也就固定下来而无法及时刷新屏幕。另外,像动画之类的显示效果,动态文档也无法提供。
有两种技术可用于浏览器屏幕显示的连续更新。一种是服务器推送(server push):将所有的工作都交给服务器。服务器不断地运行与动态文档相关联的应用程序,定期更新信息,并发送更新过的文档。
尽管这样可以达到连续更新的目的,但这也有很大的缺点。首先,为了满足大量客户的请求,服务器就要运行很多推送程序,带来繁重的开销。其次,服务器要为每一个浏览器客户维持一个不释放的TCP连接。随着TCP连接的数目增加,每个连接分配到的网络带宽就下降,导致网络传输时延增大。
另一种提供屏幕连续更新的技术是活动文档(active document)。这种技术把所有的工作都转移给浏览器。每当浏览器请求一个活动文档时,服务器就返回一段活动文档程序副本,该副本在浏览器端运行。这时,活动文档程序可与用户直接交互,并改变屏显。只要用户运行活动文档程序,活动文档的内容就可以连续改变。由于活动文档技术不需要服务器的连续更新传送,对网络带宽的要求也不会太高。
从传送的角度看,浏览器和服务器都把活动文档看成是静态文档。在服务器上的活动文档的内容是不变的,这点和动态文档是不同的。浏览器可在本地缓存一份活动文档的副本。活动文档还可压缩,以便于存储和传送。另一点要注意的是,活动文档本身并不包括其运行所需的全部软件,大部分的支持软件事先集成在浏览器中。
实现活动文档的语言包括JavaScript等。Java Applet虽然也可以开发活动文档,但现在已经被弃用。
动态网页和静态网页的一个重要区别是:网页是否能够和自己在服务器端编写的应用程序进行交互。
2.3 电子邮件
简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)是Internet电子邮件的核心。SMTP将邮件从发件人的邮件服务器传输到收件人的邮件服务器。SMTP比HTTP古老得多。

SMTP规定了14条命令和21种应答信息。每条命令用几个字母组成,而每一种应答信息一般只有一行信息,由一个3位数字的代码开始,后面附上(也可不附上)很简单的文字说明。

客户端SMTP(在发送邮件服务器主机上运行)通过TCP建立到服务器SMTP(在接收邮件服务器主机上运行)的端口25的连接。若服务器故障,则稍后再试。建立连接后,服务器和客户端执行应用层握手。在SMTP握手阶段,SMTP客户端指示发件人和收件人的邮件地址。客户端和服务器相互介绍后,客户端发送报文。SMTP依靠TCP的可靠数据传输服务将报文正确发送到服务器。如果还有其它报文要发送,客户端在同一TCP连接上重复此过程;否则,它指示TCP关闭连接。邮件服务器还要向发信人报告邮件传送的情况(如,已交付、被拒绝、丢失等)。

即使两台邮件服务器位于两个半球,SMTP通常也不使用中间邮件服务器来发送邮件。如果发送方的服务器在香港,接收方服务器在St Louis,则位于香港和St Louis的TCP连接也是直接的。假设接收方的邮件服务器故障,邮件将保留在发送方的邮件服务器中,过后会再次尝试。邮件不会放置在中间服务器中。

接下来,让我们看一下在SMTP客户端(C)和SMTP服务器(S)之间交换的邮件的示例。客户端与服务器的主机名分别是student.oust.edu.cn和oest.no.jasmine.org。以C:开头的ASCII文本行是客户端发送到其TCP套接字的行,而以S:开头的ASCII文本行服务器发送到其TCP套接字的行。一旦建立TCP连接,下面的对话就会开始:

S: 220 oest.no.jasmine.org
C: HELO student.oust.edu.cn
S: 250 Hello student.oust.edu.cn, pleased to meet you
C: MAIL FROM: [email protected]
S: 250 [email protected] … Sender ok
C: RCPT TO: [email protected]
S: 250 [email protected] … Recipient ok
C: DATA
S: 354 Enter mail, end with ”.” on a line by itself
C: Do you like the science fiction novel Defense of Data?
C: Is there an ongoing film adaptation of it?
C: .
S: 250 Message accepted for delivery
C: QUIT
S: 221 oest.no.jasmine.org closing connection

在上面的示例中,我们可以看出电子邮件的地址的格式是:
<用户名>@<邮件服务器的域名>
这个格式是TCP/IP体系的电子邮件系统规定的。“@”读作at,表示“在”。用户名就是收件人的邮箱名,由收件人在注册邮箱时自行定义。该名称在同一邮件服务器中必须唯一。邮件服务器要负责检查该用户名在本服务器中的唯一性,这样就保证了每个电子邮件地址在世界范围内都是唯一的。发送方的电子邮件软件只使用域名来选择目的地。
客户端从邮件服务器student.oust.edu.cn向邮件服务器oest.no.jasmine.org发送报文:
你喜欢长篇科幻小说《数据保卫战》吗?它是否正被改编为电影?
作为对话的一部分,客户发出了五个命令:HELO,MAIL FROM,RCPT TO,DATA和QUIT。这些命令的意义是不言自明的。客户端还发送一个由单句点组成的行,该行将报文的结尾指示给服务器。服务器发出对每个命令的答复,每个答复都有一个代码和一些(可选的)英语说明。SMTP使用持久连接:如果发送邮件服务器有多封邮件要发送到同一接收邮件服务器,则它通过同一TCP连接发送所有邮件。对于每份报文,客户端以一个新的MAIL FROM:开始该过程,以一个单独的句号指定报文的结尾,仅在所有报文发送之后才发出QUIT。

注意:发送成功不等于收件人读取了这个邮件。接收方的邮件服务器也可能接着就出了故障,使收到的邮件全部丢失(在收件人读取信件之前);发送的邮件也可能被邮件服务器当作垃圾邮件删除了;也可能收件人在清理自己的邮箱时,把尚未读取的邮件一起删除了。有时收件人很久没有登录邮箱,根本不知道邮箱中有来信。因此,邮件即使“发送成功”,收件人也不一定会读取到。但即便如此,基于SMTP的电子邮件通常都被认为是可靠的。

使用Telnet可以对SMTP服务器发起直接对话。执行
telnet 25
其中,是本地邮件服务器的名称。执行此操作时,您只是在本地主机和邮件服务器之间建立TCP连接。键入此行后,应立即收到220答复。然后在适当的时候发出SMTP命令HELO,MAIL FROM,RCPT TO,DATA,CRLF.CRLF和QUIT。

SMTP与HTTP两种协议都用于在主机之间传送文件。HTTP将文件(对象)从Web服务器传输到Web客户端(通常是浏览器);SMTP将文件(邮件)从一台邮件服务器传输到另一台。传输文件时,持久性HTTP和SMTP均使用持久连接。但是两者有重要的区别。首先,HTTP主要是一种内拉式协议(pull protocol):有人将信息加载到Web服务器上,用户在方便时使用HTTP从服务器拉取信息;TCP连接由要接收文件的机器启动。相比之下,SMTP主要是一种外推式协议(push protocol):发送邮件服务器将文件推送到接收邮件服务器;TCP连接是由要发送文件的计算机发起的。
第二个区别是SMTP要求每条报文(包括正文)都采用7位ASCII格式。如果报文包含非ASCII字符(例如带有重音符号的法语字符)或二进制数据(例如图像文件),则必须将报文编码为7位ASCII。HTTP没有此限制。
第三个重要区别涉及如何处理由文本、图像及其它媒体类型组成的文档。HTTP将每个对象封装在自己的HTTP响应报文中。SMTP将邮件的所有对象放入一封邮件中。

发送电子邮件时,包含外围信息的报头位于报文本身之前。报头行和正文由空行(CRLF)分隔。 RFC 5322指定了邮件报头行的确切格式及其语义。与HTTP一样,每个报头行均包含可读文本,文本由关键字、冒号和值组成。一些关键字是必需的,其它则是可选的。每个报头都必须有一个From:报头行和一个To:报头行;可以包括Subject:报头行以及其它可选报头行。这些报头行与我们在2.4.1节中研究过的SMTP命令不同(即使它们包含一些相同的词,如from、to)。那部分中的命令是SMTP握手协议的一部分;这里的报头行是邮件本身的内容的一部分。典型的邮件报头行如下所示:
From: [email protected]
To: [email protected]
Subject: I am planning a departure to UIO following the schedule of School of Literature of OUST. Hope you will come.
报文标题之后,空行;然后出现正文(以ASCII表示)。
邮件首部还可以有一项抄送Cc:(Carbon copy),意思是留下一个“复写副本”。这是借用旧的名词,表示应给某某人发送(抄送)一个邮件副本。有些邮件系统允许用户使用关键字Bcc(Blind carbon copy)来实现盲复写副本。这是使发件人能将邮件的副本送给某人,但不希望此事为收件人知道。Bcc又称为暗送。
首部还可以有Date:,表示发件日期。这一项一般与“From:”一起,由系统自动填入。
另一个关键字是Reply-To,即对方回信所用的地址。这个地址可以与发件人发信时所用的地址不同。例如有时到外地借用他人的邮箱给朋友发邮件,但仍希望对方将回信发到自己的邮箱。这一项可以事先设置好,无需每次写信时设置。

SMTP将邮件从Alice的邮件服务器传递到Bob的以后,邮件就放在Bob的邮箱中。我们假定Bob通过登录服务器主机然后执行在该主机上的邮件阅读器来读取邮件。直到1990年代初,这都是标准的方式。如今,邮件访问使用的是C-S结构:用户在客户端读取邮件。本地PC上的邮件客户端使用户可以享受一系列丰富的功能,包括查看多媒体和附件。
理论上,Bob作为收件人,也可以直接放置邮件服务器在本地PC上。通过这种方法,Alice的邮件服务器可以直接与Bob的PC对话。但这种方法存在问题。回想一下,邮件服务器管理邮箱并运行SMTP的客户端和服务器端。如果Bob的邮件服务器就是他的个人PC,则Bob的PC必须始终开机并连接到Internet,以便接收可能随时到达的新邮件。这对许多用户是不切实际的。而且,许多用户的计算机无力承担邮件服务器的负载。一般地,用户在本地PC上运行UA(如Outlook),但访问存储在始终在线的共享邮件服务器上的邮箱。该邮件服务器与其他用户共享,通常由ISP或一些公司维护。

思考一下电子邮件从Alice发送到Bob经过的路径。发送的电子邮件需要存储在Bob的邮件服务器中。要做到这点,Alice的用户代理直接将邮件发送到Bob的邮件服务器即可完成,并且这可以通过SMTP做到:SMTP是为将电子邮件从一台主机推送到另一台主机而设计的。但是,通常发件人的UA不会直接与收件人的邮件服务器对话。相反,Alice的UA使用SMTP将电子邮件推送到她的邮件服务器,然后Alice的邮件服务器使用SMTP(作为SMTP客户端)将电子邮件中继到Bob的邮件服务器。分两步主要是因为在不通过Alice邮件服务器进行中继的情况下,Alice的UA无法访问目标邮件服务器。通过让Alice首先将邮件存储在自己的邮件服务器中,Alice的邮件服务器可以反复尝试将邮件发送到Bob的邮件服务器,直到Bob的服务器开始工作为止。如果Alice的邮件服务器无故关闭,那么她可以向系统管理员或邮件运营商投诉。SMTP RFC定义了如何使用SMTP命令在多个SMTP服务器之间中继报文。

像Bob这样在本地PC上运行UA的收件人如何获取邮件服务器中的报文呢?请注意,Bob的UA无法使用SMTP来获取报文,因为获取报文是一种拉取操作,而SMTP是一种推送协议。通过引入特殊的邮件访问协议可以解决此问题,该协议将邮件从Bob的邮件服务器传输到他的PC。当前有许多流行的邮件访问协议,包括邮局协议-版本3(Post Office Protocol—Version 3,POP3),Internet邮件访问协议(IMAP)和HTTP。

POP3是一种非常简单的邮件访问协议,其功能相当有限。当用户代理(客户端)在端口110上打开与邮件服务器(服务器)的TCP连接时,POP3开始发挥作用。建立连接后,POP3经历三个阶段:授权、事务处理和更新。在授权阶段,UA发送用户名和密码(明文)以对用户进行身份验证。在事务处理阶段,UA检索报文。同样在此阶段,用户代理可以将邮件标记为删除,移除删除标记并获取邮件统计信息。更新阶段发生在客户端发出quit命令之后,结束POP3会话。这时,邮件服务器将删除标记为删除的邮件。

在POP3事务中,UA发出命令,服务器对每个命令进行回复。有两种可能的响应:+OK(有时后面跟着服务器到客户端的数据),代表先前的命令正常。服务器使用-ERR来指示前一个命令有问题。
授权阶段有两个主要命令:user 和pass 。为说明这两个命令,你可以尝试Telnet到POP3服务器,使用端口110,并发出以下命令。假设是您的邮件服务器的名称。您将看到类似以下内容:
telnet 110
+OK POP3 server ready
user bob
+OK
pass hungry
+OK user successfully logged on

使用POP3的用户代理可被配置为“下载并删除”或“下载并保留”方式。POP3用户代理发出的命令序列取决于选用哪种工作方式。使用下载并删除方式,用户代理发出list、retr和dele命令。
用户代理首先请求邮件服务器列出所有存储的报文的长度,接着取回并删除每封邮件。授权阶段以后,用户代理仅使用四个命令list、retr、dele和quit。quit命令后,POP3服务器进入更新阶段,从邮箱中删除邮件。
这种方式显然存在问题。接收方可能希望从多个设备访问邮件。当他在一个设备上查看邮件后,邮件就从服务器上删除了,在其它的机器上将不可以再查看该邮件。如使用下载并保留方式,用户代理下载某邮件后,该邮件仍保留在邮件服务器。这时就能通过不同的机器重新读取这些邮件。
在用户代理与邮件服务器之间的POP3会话期间,POP3服务器保留了一些状态信息,比如哪些用户报文被标记为删除。然而,POP3服务器并不在POP3会话过程中携带状态信息。这大大简化了POP3服务的实现。

使用POP3访问时,无法在远程服务器上建立文件夹来管理邮件,因为POP3协议没有提供这些方法。
为解决此问题,Internet报文访问协议(Internet message access protocol,IMAP)应运而生。IMAP也是一个邮件访问协议,但比POP3功能更多,也比POP3复杂得多。
IMAP服务器把每个报文与一个文件夹联系起来;当报文第一次到达服务器时,进入收件人的INBOX(收件箱)。收件人能把邮件移到一个新的、用户创建的文件夹中,再进行阅读或删除。IMAP为用户提供了创建文件夹、移动邮件,以及按指定条件去查询匹配的邮件的命令。与POP3不同,IMAP服务器维护了IMAP会话的用户状态信息,例如,文件夹名,以及哪些报文与哪些文件夹相关联。
IMAP允许用户代理仅获取报文的一部分。例如,只读取一个报文的首部,或正文的一部分。当网络非常慢的时候,这一点极其有用。这允许用户不用等待邮箱中的所有邮件或邮件中的音视频等较大的片段加载完毕。
与POP3不同,IMAP有一个缺点:如果用户没有将邮件复制到自己的计算机上,则邮件一直存放在IMAP服务器上。要想对自己的邮件进行各类操作,必须先上网。因此,IMAP是联机协议,POP3是脱机协议。

今天,大家一般使用浏览器收发邮件。20世纪90年代中期,Hotmail引入了基于Web的访问界面。谷歌、雅虎以及几乎所有重要的大学或者公司也提供了基于Web的电子邮件。使用这种服务时,UA是浏览器,用户和邮箱的通信通过HTTP进行。当收件人想访问邮件时,该邮件报文从邮件服务器发送到用户的浏览器,使用HTTP而不是POP3或者IMAP。当发件人要发送邮件时,该邮件报文从发件人的浏览器发送到他的邮件服务器,使用HTTP而不是SMTP。只是,邮件服务器在与其它的邮件服务器收发邮件时,仍然使用SMTP。
所以,不要把邮件读取协议POP3或IMAP与邮件传送协议SMTP弄混。发件人的用户代理向发送方邮件服务器发送邮件可以使用SMTP或HTTP。发送方邮件服务器向接收方邮件服务器发送邮件使用SMTP。而POP3或IMAP则是用户代理从接收方邮件服务器上读取邮件所使用的协议。

SMTP具有许多出色的特质(不然也不会在Internet上如此普遍),但也有不少缺点。例如:
(1)它将所有邮件的正文(不只是标题)限制为7位ASCII。这种限制在1980年代初期是有意义的,当时传输能力不足,没有人通过电子邮件发送大型附件。但在如今,这个限制有点麻烦:它要求多媒体数据和可执行文件等在通过SMTP发送之前必须先编码为ASCII,传输后再解码。而HTTP则不需要在传输前这样编码。并且,这种编码未形成正式标准或事实上的标准。
(2)SMTP传送的邮件是明文,不利于保密。
(3)SMTP服务器会拒绝超过一定长度的邮件。
(4)某些SMTP的实现并没有完全按照SMTP的互联网标准。常见的问题如下:
•回车、换行的删除和增加;
•超过76个字符时的处理:截断或自动换行;
•后面多余空格的删除;
•将制表符tab转换为若干个空格。

为了解决这些问题,新的方案被提出来了。2008年10月颁布的RFC 5321对SMTP进行了扩充,成为扩展SMTP(Extended SMTP,ESMTP)。RFC 5321在许多命令中增加了扩展的参数。新增功能有:客户端的鉴别,服务器接受二进制报文,服务器接受分块传送的大报文,发送前先检查报文的大小,使用运输层安全协议TLS(8.6节),以及使用国际化地址等。考虑到现在的许多SMTP邮件服务器可能还没有升级到ESMTP,因此特规定使用ESMTP的客户端在准备传送报文时,不是发送HELO而是发送EHLO报文。如果EHLO报文被对方服务器拒绝,就表明对方仍然是一个标准的SMTP邮件服务器,因而就要按照原先的SMTP参数进行邮件的传送。如果EHLO报文被接受了,那么客户端就可以使用ESMTP扩展的参数传送报文了。

多用途互联网邮件扩展MIME(Multipurpose Internet Mail Extensions)可以解决大部分SMTP存在的缺陷。MIME并没有改动或取代SMTP。MIME的意图是继续使用原来的邮件格式,但增加了邮件主体的结构,并定义了传送非ASCII码的编码规则。也就是说,MIME邮件可在现有的电子邮件程序和协议下传送。

MIME主要包括以下三部分内容:
(1) 5个新的邮件首部字段,它们可包含在原来的邮件首部中。这些字段提供了有关邮件主体的信息。
(2) 定义了许多邮件内容的格式,对多媒体电子邮件的表示方法进行了标准化。
(3) 定义了传送编码,可对任何内容格式进行转换,而不会被邮件系统改变。
为适应于任意数据类型和表示,每个MIME报文包含告知收件人数据类型和使用编码的信息。MIME把增加的信息加入到原来的邮件首部中。
下面是MIME增加的5个新的邮件首部的名称及其意义(有的可以是选项)。
(1) MIME-Version: 标志MIME的版本。若无此行,则为英文文本。
(2) Content-Description: 这是可读字符串,说明此邮件主体是否是图像、音频或视频。
(3) Content-Id: 邮件的唯一标识符。
(4) Content-Transfer-Encoding: 在传送时邮件的主体是如何编码的。
(5) Content-Type: 说明邮件主体的数据类型和子类型。上述的前三项的意思很清楚,因此只介绍后两项。

下面介绍三种常用的内容传送编码(Content-Transfer-Encoding)。
最简单的编码就是7位ASCII码,每行不能超过1000个字符。MIME对这种由ASCII码构成的邮件主体不进行任何转换。

另一种编码称为quoted-printable,这种编码方法适用于只有少量非ASCII码的数据。这种编码方法的要点就是对于所有可打印的ASCII码,除特殊字符“=”外都不改变。等号和不可打印的ASCII码以及非ASCII码的数据的编码方法是:先将每个字节的二进制代码用两个十六进制数字表示,然后在前面再加上一个等号“=”。例如,汉字的“系统”的二进制编码是:11001111101101011100110110110011(共32位,四个字节都不是ASCII码),用十六进制表示为:CFB5CDB3;用quoted-printable编码表示为:=CF=B5=CD=B3。这12个字符都是可打印的ASCII字符,占用96位,和原来的32位相比,开销达200%。而等号“=”的二进制代码为00111101,即十六进制的3D,因此等号的quoted-printable编码为“=3D”。

对于任意的二进制文件,可用base64编码。这种编码方法先把二进制代码划分为24位长的单元,然后把每个24位单元划分为4个6位组。每一个6位组按以下方法转换成ASCII码:6位的二进制代码共有64种不同的值,从0到63。用A表示0,用B表示1,等等。26个大写字母排列完毕后,排26个小写字母,再排10个数字,最后用“+”和“/”分别表示62和63。再用两个连在一起的等号“==”和一个等号分别表示最后一组的代码只有8位或16位。回车和换行都忽略,它们可在任何地方插入。

MIME标准规定Content-Type说明必须含有两个标识符,即内容类型(type)和子类型(subtype),中间用“/”分开。
MIME标准原先定义了7个基本内容类型和15种子类型(见RFC 1521,但这个文档已被列入“陈旧的”。除了内容类型和子类型,MIME允许发件人和收件人自己定义专用的内容类型。但为避免可能出现名字冲突,标准要求为专用的内容类型选择的名字要以字符串X-开始。但是,后来陆续出现了几百个子类型,而且子类型的数目还在不断地增加。

MIME的内容类型中的multipart是很有用的,因为它使邮件增加了相当大的灵活性。MIME标准为multipart定义了四种可能的子类型,每个子类型都提供重要功能。
(1)mixed子类型允许一份报文含有多份相互独立的子报文,每个子报文可以有自己的类型和编码。mixed子类型报文使用户能够在单个报文中附上文本、图形和声音,或者用额外数据发送一个备忘录,类似商业信笺含有的附件。在mixed后面还用到一个关键字Boundary=,此关键字定义了分隔报文各部分的字符串(由邮件系统定义),只要在邮件的内容中不会出现这样的字符串即可。当某一行以两个连字符“–”开始,后面紧跟上述的字符串,就表示下面开始另一子报文。
(2)alternative子类型允许单个报文含有同一数据的多种表示。当给多个使用不同硬件和软件系统的收件人发送备忘录时,这种类型的multipart报文很有用。例如,用户可同时用普通的ASCII文本和格式化的形式发送文本,从而允许拥有图形功能的计算机用户在查看图形时选择格式化的形式。
(3)parallel子类型允许单个报文含有可同时显示的各个子部分(例如,图像和声音子部分必须一起播放)。
(4)digest子类型允许单个报文含有一组其它报文(如从讨论中收集电子邮件报文)。
下面是一封MIME邮件,它包含一个简单解释的文本和含有非文本信息的照片。邮件中第一部分的注解说明第二部分含有一张照片。

上面最后一行表示boundary的字符串后面还有两个连字符表示整个multipart的结束。
2.4 DNS
人类能以很多方式标识身份。例如名字、社会安全号码或驾驶证号。尽管它们都可以标识一个人,但是在特定条件下,总有更适合的方法。IRS(美国那个声名狼藉的税务征收机构)的计算机更喜欢使用定长的社安号而不是出生证书上的姓名。普通人乐于使用更好记的姓名而不是社安号。想想看:“你好,我叫132-67-9875。请找一下我的丈夫178-87-1146”。这种标识方式是不是很折磨人?
Internet上的主机也可以使用多种方式进行标识。一种标识方法是主机名(hostname),如www.instagram.com,www.google.com,gaia.cs.umass.edu和cis.poly.edu等,这些名字便于记忆。然而,主机名只提供了很少或没有提供主机在Internet中的位置信息:www.eurecom.fr以国家码结束,告诉我们该主机很可能在法国,仅此而已。并且,主机名可能由不定长的字母数字组成,这增加了处理难度。因此,主机常使用IP地址标识。第4章将详细讨论IP地址,这里只简略介绍。一个IPv4地址由4字节组成,具有层次结构。例如121.7.106.83这样一个IP地址,每个字节都被句点分隔,取值范围是[0,255]的整数。我们说IP地址具有层次结构,是因为当从左至右扫描它时,我们会得到越来越具体的关于主机位于Internet何处的信息(即在众多网络的哪个网络里)。

为了折中这些不同的偏好,需要能转换(解析,resolve)主机名到IP地址的服务。这就是域名系统(Domain Name System,DNS)的主要任务。DNS是:①一个由分层的DNS服务器实现的分布式数据库;②一个使主机能查询分布式数据库的应用层协议。DNS服务器常常是运行BIND(Berkeley Internet Name Domain)软件的UNIX机器。DNS协议运行在UDP上,使用53端口。
DNS通常由其它应用层协议使用,包括HTTP、SMTP和FTP,将用户提供的主机名解析为IP地址。

当用户主机上的浏览器(HTTP客户)请求URL:www.oust.edu.cn/index.html时会发生什么呢?为了使用户主机能将一份HTTP请求报文发送到www.oust.edu.cn,主机必须获得www.oust.edu.cn的IP地址。其做法如下:
1)用户主机上运行着DNS应用的客户端。
2)浏览器从上述URL中提取主机名www.oust.edu.cn,传给DNS应用的客户端。
3)DNS客户向DNS服务器发送一个包含主机名的请求。
4)DNS客户最终会收到一份响应报文,其中包含该主机名的IP地址。
5)一旦浏览器接收到来自DNS的该IP地址,它能够向位于该IP地址80端口的HTTP服务器进程发起一个TCP连接。
从这个例子中,可以看到DNS给使用它的Internet应用带来了额外的时延,有时还相当可观。幸运的是,想获得的IP地址通常就缓存在附近的DNS服务器,这有助于减少DNS的网络流量和平均时延。

早在ARPANET时代,整个网络上只有数百台计算机,那时使用一个叫做hosts的文件,列出所有主机名字和相应的IP地址。只要用户输入一台主机名字,计算机就可很快地把这台主机名字转换成机器能够识别的二进制IP地址。如今,在运行Windows 10的计算机上仍然能找到hosts,它位于%windir%\System32\drivers\etc目录下。

域名系统其实就是名字系统。为什么不叫“名字”而叫“域名”呢?这是因为:这种互联网的命名系统使用了许多的域,因此就出现了“域名”这个名词。“域名系统”很明确地指明这种系统是用在互联网中的。
早期的互联网使用非等级的名字空间,其优点是名字简短。但当互联网用户数急剧增加时,用非等级的名字空间来管理一个很大的而且是经常变化的名字集合是非常困难的。因此,互联网后来采用了层次树状结构的命名方法,就像全球邮政系统和电话系统那样。采用这种命名方法,任何一个连接在互联网上的主机或路由器,都有一个唯一的层次结构的名字,即域名(domain name)。这里,域(domain)是名字空间中一个可被管理的划分。域还可以划分为子域,而子域还可继续划分为子域的子域,这样就形成了顶级域、二级域、三级域,等等。

从语法上讲,每一个域名都由标号(label)序列组成,而各标号之间用点隔开(请注意,是小数点“.”不是中文的句号“。”)。例如:域名
cs.oust.edu.cn
从左到右的四个标号分别叫做四级域名、三级域名、二级域名和顶级域名。
DNS规定,域名中的标号都由英文字母和数字组成,每个标号不超过63个字符,也不区分大小写。标号中除连字符(-)外不能使用其它标点。级别最低的域名写在最左边,级别最高的顶级域名写在最右边。由多个标号组成的完整域名不得超过255个字符。DNS既不规定一个域名需要包含多少个下级域名,也不规定每一级的域名代表什么意思。各级域名由其上一级的域名管理机构管理,而顶级域名则由互联网名称与数字分配机构(Internet Corporation for Assigned Names and Numbers,ICANN)管理。这种方法使每一个域名在整个互联网范围内是唯一的,并且也容易设计出查找域名的机制。
域名只是个逻辑概念,并不代表计算机所在的物理地点。这里需要注意,域名中的“点”和点分十进制IP地址中的“点”并无一一对应的关系。点分十进制IPv4地址一定包含三个“点”,但域名中“点”的数目不一定是三个。

顶级域名共分为三大类:
(1)国家顶级域名nTLD:
采用ISO 3166的规定。如:cn表示中国,us表示美国,uk表示英国,等等。
国家顶级域名又常记为ccTLD(cc表示国家代码country-code)。ccTLD也包括某些地区的域名,如香港特别行政区(hk)和台湾省(tw)也都是ccTLD里面的顶级域名。此外,国家顶级域名可以使用一个国家自己的文字。例如,中国可以有“.cn”、“中国”和“中國”三种不同形式的域名。
(2)通用顶级域名gTLD:
美国的gTLD主要有:com(公司企业),net(网络服务机构),org(非营利性组织),int(国际组织),edu(美国专用的教育机构),gov(美国的政府部门),mil表示(美国的军事部门)。后来又陆续增加了一些gTLD。
(3)基础结构域名(infrastructure domain):这种顶级域名只有一个,即arpa,用于反向域名解析(将IP地址转换为域名),因此又称为反向域名。

ICANN于2011年6月20日在新加坡会议上正式批准新顶级域名(New gTLD),因此任何公司、机构都有权向ICANN申请新的顶级域。新顶级域名作为后缀,使企业域名具有了显著的、强烈的标志特征,因此被认为是真正的企业网络商标。新顶级域名是企业品牌战略发展的重要内容,其申请费很高(18万美元),并在2013年开始启用。目前已有一些由两个汉字组成的中文的顶级域名出现了,例如,商城、公司、新闻等。2016年,在ICANN注册的中文顶级域名已有60个。

在国家顶级域名下注册的二级域名均由该国家自行确定。例如,顶级域名为jp的日本,将其教育和企业机构的二级域名定为ac和co,而不用edu和com。
我国把二级域名划分为“类别域名”和“行政区域名”两大类。“类别域名”共7个,分别为:ac(科研机构),com(工、商、金融等企业),edu(教育机构),gov(政府机构),mil(国防机构),net(提供互联网络服务的机构),org(非营利组织)。
“行政区域名”共34个,适用于我国的各省、自治区、直辖市。例如:bj(北京市),js(江苏省),等等。
关于我国的互联网络发展现状以及各种规定(如申请域名的手续),均可在中国互联网网络信息中心(CNNIC)找到。在我国,中国教育与科研网络信息中心负责管理edu.cn。其它域名可向中国互联网络信息中心CNNIC申请。不同机构管理名字的一部分。

这里还要强调,互联网的名字空间是按照机构的组织来划分的,与物理的网络无关,与日后将学习的IP地址中的“子网”也没有关系。

除了进行主机名到IP地址的转换外,DNS还具有一些重要的功能:
·主机别名(host aliasing)。有着复杂主机名的主机能拥有若干个别名。例如,主机relay-wi.us.3134.com可能还有两个别名:3134.com和www.3134.com。此情况下,relay-wi.us.3134.com也称为规范主机名(canonical hostname)。主机别名一般比主机规范名更容易记忆。应用程序可以调用DNS来获得主机别名对应的规范主机名以及主机的IP地址。
·邮件服务器别名(mail server aliasing)。人们也希望邮件地址好记。例如,Andy的邮件地址形如[email protected]这样简单。不过,邮件服务器的主机名可能更为复杂,例如规范主机名可能像relay1.west-coast.jasmine.org那样。电子邮件应用程序可以调用DNS,对提供的主机名别名进行解析,以获得规范主机名及IP地址。事实上,MX记录(见后文)允许一个公司的邮件服务器和Web服务器使用相同(别名化的)的主机名。
·负载分配(load distribution)。DNS也用于在多台服务器之间进行负载分配。繁忙的站点被分布在多台服务器上,每个都有着不同的IP地址。这时,一个IP地址集合与同一个规范主机名相联系。DNS数据库中存储着这些IP地址集合。当客户对映射到某地址集合的名字发出DNS请求时,该服务器用IP地址的整个集合进行响应,但在每个响应中依次给出这些地址。因为客户通常总是向IP地址排在最前面的服务器发送HTTP请求报文,所以DNS就在所有这些冗余的Web服务器之间循环分配了负载。DNS的循环同样可以用于邮件服务器,因此,多个邮件服务器可以具有相同的别名。一些内容分发公司如Akamai也以更加复杂的方式使用DNS,以提供Web内容分发(2.6节)。
DNS是一个复杂的系统,我们在这里只是就其运行的主要方面进行学习。

与HTTP、FTP和SMTP协议一样,DNS协议是应用层协议,原因有:①使用C-S模式运行在通信的端系统之间;②在通信的端系统之间通过下面的端到端运输协议来传送DNS报文。某种意义上,DNS的作用非常不同于Web、文件传输以及电子邮件。不同之处在于,DNS不直接和用户打交道。相反,DNS是为Internet上的用户应用程序及其它软件提供一种核心功能:将主机名转换为IP地址。1.2节提到,Internet体系结构的复杂性大多位于网络的边缘。DNS通过采用位于网络边缘的客户和服务器,实现了关键的名字到地址转换功能,它也是这种设计原理的另一个范例。

下面给出DNS工作过程的概括,讨论将集中在主机名到IP地址的转换方面。
应用程序需要将主机名转换为IP地址时,需要调用DNS的客户端,并指明需要被转换的主机名(在很多基于UNIX的机器上,执行转换需要调用函数gethostbyname())。用户主机上的DNS接收到后,向网络中发送一份DNS查询报文。所有的DNS请求和回答报文使用UDP数据报经端口53发送。而后,用户主机上的DNS接收到一份DNS回答报文,报文中的转换结果被传递到调用DNS的应用程序。因此,从用户主机上的应用程序的角度,DNS是一份提供简单、直接的转换服务的黑盒子。事实上,这个黑盒非常复杂,它由分布于全球的大量DNS服务器以及定义了DNS服务器与查询主机通信方式的应用层协议组成。

如果在Internet上只使用一台DNS服务器,那么客户直接将所有查询发往该服务器,同时该服务器直接对所有的查询客户响应。尽管这种设计很简单,但它不适用于Internet,因为Internet有着数量巨大(并持续增长)的主机。这种集中式设计的问题包括:
·单点故障(a single point of failure)。如果该DNS服务器崩溃,整个Internet将随之瘫痪。
·通信容量(traffic volume)。单一的DNS服务器不得不处理所有的DNS查询(为上亿台主机产生的所有HTTP请求报文和电子邮件报文服务)。
·远距离的集中式数据库(distant centralized database)。单个DNS服务器不可能距离所有客户都比较近。如果将它放在纽约市,那么来自澳大利亚的查询必须绕到地球的另一边,中间也许还要经过低速和拥塞的链路。这将导致严重的时延。
·维护(maintenance)。单个DNS服务器将不得不为所有的Internet主机保留记录。这不仅将使这个中央数据库极度庞大,而且它还不得不为解析每个新添加的主机而频繁更新。
总的来说,在单一DNS服务器上运行集中式数据库完全没有可扩展能力(scalability)。因此,DNS采用了分布式的设计方案。事实上,DNS是一个在Internet上实现分布式数据库的精彩范例。

为了处理扩展性问题,DNS使用了大量的服务器,它们以层次方式组织,并且分布在全世界。没有一台DNS服务器拥有Internet上所有主机的IP地址。大致说来,有3类的DNS服务器:根DNS服务器、顶级域(Top-Level Domain,TLD)DNS服务器和权威(authoritative)DNS服务器。假定一个DNS客户要查询www.amazon.com的IP地址。粗略地讲,将发生下列事件:
客户首先与根服务器之一联系,它将返回顶级域名com的TLD服务器的IP地址。
客户与TLD服务器之一联系,后者返回amazon.com的权威服务器的IP地址。
最后,该客户与amazon.com权威服务器之一联系,它为主机名www.amazon.com返回其IP地址。
先来了解一下这3种类型的DNS服务器:

•根DNS服务器。有许多根域名服务器遍及全世界,由13个不同的组织管理。根服务器提供顶级域DNS服务器的IP地址。所有的根域名服务器都知道所有的顶域服务器的域名和IP地址。任何一台DNS服务器只要无法解析某个主机名,一般而言首先要求助于根服务器。如果所有的根服务器都瘫痪了,那么整个互联网的DNS系统就无法再正常工作。
到2016年2月,全世界已经在588个地点(这个值还在不断增加)安装了根域名服务器,但这么多的根域名服务器却只使用13个不同IP地址的域名,即a.root-servers.net,b.root-servers.net,……, m.root-servers.net。每个域名下的根域名服务器由专门的公司或美国政府的某个部门负责运营。但请注意,虽然互联网的根域名服务器总共只有13个域名,但这不表明根域名服务器是由13台机器所组成(如果仅有13台机,根本不可能为全世界的互联网用户提供令人满意的服务)。实际上,在互联网中是由13套装置(13 installations)构成这13组根域名服务器(美国、英国、瑞典和日本分别占有10组、1组、1组和1组)。每一套装置在很多地点安装根域名服务器(也称镜像根服务器),但都使用同一个域名。负责运营根域名服务器的机构大多在美国,但所有的根域名服务器却分布在全世界。为了提供更可靠的服务,每一个地点的根域名服务器往往由多台机器组成;为了安全起见,有些根服务器的具体地点还是保密的。现在世界上大部分DNS域名服务器,都能就近找到一台根服务器查询IP地址(现在这些根服务器都已增加了IPv6地址)。为了方便,人们常用从A到M的前13个英文字母中的一个,来表示某组根服务器。
各组根服务器的运营方如下:

由于根服务器采用了任播(4.3节)技术,因此当DNS客户向某台根服务器的IP地址发出查询报文时,互联网上的路由器就能找到离这个DNS客户最近的一台根域名服务器。这不仅加快了DNS的查询过程,也更合理地利用了互联网的资源。
目前根域名服务器的分布仍然很不均衡。在北美,平均每375万网民就可以分摊到一台根域名服务器;而在亚洲,平均超过2千万网民才分摊到一个根域名服务器。这使亚洲网民的上网速度明显低于北美。
截至2020年8月12日,我国根域名服务器的结点共有28个。

•顶级域DNS服务器。对于每个顶级域(如com、org、net、edu和gov)和所有国家的顶级域(如uk、fr、ca和jp),都有TLD服务器(或集群)。Verisign Global Registry Services公司维护com顶级域的TLD服务器,Educause公司维护edu顶级域的TLD服务器。支持TLD的网络基础设施是大而复杂的。TLD服务器提供了权威DNS服务器的IP地址。有时候,TLD服务器也可以直接给出目标主机的IP地址。

•权威DNS服务器。一台服务器所负责管辖的(或有权限的)范围叫做区(zone)。各单位根据具体情况来划分自己管辖的区,每一个区设置相应的权限域名服务器,用来保存该区中的所有主机的域名到 IP 地址的映射。在Internet上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织都具有权威DNS服务器,提供公共可访问的DNS记录。织机构可以实现自己的权威DNS服务器,或支付费用,使用服务提供商的权威DNS服务器。多数大学和大公司实现和维护它们自己基本和辅助(备份)的权威DNS服务器。当主域名服务器故障时,辅助域名服务器可以保证DNS的工作不会中断。主域名服务器定期把数据复制到辅助域名服务器中,而更改数据只能在主域名服务器中进行。这样就保证了数据的一致性。

DNS服务器的管辖范围不是以“域”为单位,而是以“区”为单位。相比之下,“域”是为了方便对主机名的管理而划分的。区是DNS服务器实际管辖的范围。区可能等于或小于域,但一定不能大于域。

根、TLD和权威DNS服务器都处在该DNS服务器的层次结构中,如上图。还有另一类重要的DNS服务器:本地DNS服务器(local DNS server)也称默认域名服务器。严格说来,本地DNS服务器并不属于DNS服务器的层次结构,但它对DNS层次结构是至关重要的。每个ISP(如一个居民区的ISP或一个机构的ISP)都具有本地DNS服务器(默认名字服务器)。当主机与某个ISP连接时,该ISP提供一台主机的IP地址,该主机具有一台或多台其本地DNS服务器的IP地址(通常通过DHCP,见第4章)。通过访问Windows或UNIX的网络状态窗口,用户容易确定他的本地DNS服务器的IP地址。主机的本地DNS服务器通常邻近本主机。对机构ISP而言,本地DNS服务器可能就与主机在同一个局域网中;对居民区ISP来说,本地DNS服务器通常与主机相隔不超过几台路由器。当主机发出DNS请求时,该请求被发往本地DNS服务器,它起着代理的作用,并将该请求转发到DNS服务器层次结构中,我们下面将更为详细地讨论。

来看一个典例,设主机cse.nyu.edu想知道主机gaia.cs.umass.edu的IP地址;NYU的cse.nyu.edu主机的本地DNS服务器为dns.nyu.edu;gaia.cs.umass.edu的权威DNS服务器为dns.umass.edu。
主机cse.nyu.edu首先向本地DNS服务器dns.nyu.edu发送DNS查询报文,后者含有需要转换的主机名gaia.cs.umass.edu。
本地DNS服务器将该报文转发到根DNS服务器。根DNS服务器注意到其edu前缀,向本地DNS服务器返回负责edu的TLD的IP地址列表。
该本地DNS服务器则再次向这些TLD服务器之一发送查询报文。TLD服务器注意到umass.edu前缀,并用权威DNS服务器的IP地址进行响应,该权威DNS服务器是负责UMass Amherst的dns.umass.edu。
最后,本地DNS服务器直接向dns.umass.edu重发查询报文,dns.umass.edu用gaia.cs.umass.edu的IP地址进行响应。注意到在本例中,为了获得一台主机名的映射,共发送了8份DNS报文:4份查询报文和4份回答报文。

前面的例子假设了TLD服务器知道用于主机的权威DNS服务器的IP地址。这种假设并不总是正确:TLD服务器也许只是知道中间的某个DNS服务器,该中间DNS服务器依次才能知道用于该主机的权威DNS服务器。
在前面例子的基础上,假设UMass Amherst的每个系都有自己的DNS服务器,每个系的DNS服务器是本系所有主机的权威服务器。在这种情况下,当中间DNS服务器dns.umass.edu收到了对某主机的请求时,该主机名以cs.umass.edu结尾,它向dns.nyu.edu返回dns.cs.umass.edu的IP地址,后者是所有以cs.umass.edu结尾的主机的权威服务器。本地DNS服务器dns.nyu.edu则向权威DNS服务器发送查询,该权威DNS服务器向本地DNS服务器返回所希望的映射,该本地服务器依次向请求主机返回该映射。在这个例子中,共发送了10份DNS报文。

下面介绍递归查询(recursive query)和迭代查询(iterative query)。
所谓递归查询就是:如果主机询问的本地域名服务器不知道被查询域名的IP地址,那么本地域名服务器就以DNS客户的身份,向上级域名服务器继续发出查询请求报文,替该主机继续查询,而不是让该主机自己进行下一步的查询。因此,递归查询要么返回所要查询的IP地址,要么因为无法查询到结果而报错。
迭代查询的特点是:当级别更高的域名服务器收到迭代查询请求报文时,要么给出所查的IP地址,要么告诉DNS客户,下一步应向哪一个DNS服务器进行查询。然后DNS客户进行后续的查询,而不代替DNS客户进行后续的查询。
上例中,从cse.nyu.edu到其本地DNS服务器dns.nyu.edu的查询是递归查询,因为本地DNS服务器以自己的名义请求dns.nyu.edu继续查询。后继的3个查询是迭代查询,因为所有的回答都是、直接返回给dns.nyu.edu。理论上,任何DNS查询既可以是迭代的也可以是递归的。一般而言:从请求主机到本地DNS服务器的查询是递归的,其余的查询是迭代的。
当一个权威域名服务器不能给出最后的查询回答时,也会告诉DNS客户,下一步应当找哪一个权威域名服务器。

为了改善时延并减少在网上到处传输的DNS报文的数量,DNS广泛使用了DNS缓存(DNS caching)。DNS缓存的原理非常简单。在一个请求链中,当某DNS服务器接收一个DNS响应(例如,包含某主机名到IP地址的映射)时,它将其缓存在本地存储器中。当另一个对相同主机名的查询到达该DNS服务器时,就能够提供所需的IP地址,即使它不是该主机名的权威服务器。
主机和主机名与IP地址的映射并不是永久的,DNS服务器在一段时间后(通常是两天)将丢弃缓存的信息。
有了缓存,本地DNS服务器可以立即返回目标主机的IP地址,而不必查询其它DNS服务器。本地DNS服务器也能够缓存TLD服务器的IP地址,因而允许本地DNS绕过查询链中的根DNS服务器。事实上,除了少数DNS查询,一般情况下无需再去询问根服务器,这就是缓存的功劳。
不但在本地域名服务器中需要高速缓存,在主机中也很需要。许多主机在启动时,从本地域名服务器下载域名和地址的全部数据库,维护存放自己最近使用的域名的高速缓存,并且只在从缓存中找不到域名时才使用域名服务器。维护本地域名服务器数据库的主机应定期检查域名服务器以更新映射信息,且必须及时从缓存中删掉无效的项。由于域名改动并不频繁,大多数网点不需花太多精力就能维护数据库的一致性。

共同实现DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record,RR)。RR提供了主机名到IP地址的映射。每个DNS回答报文包含了一条或多条资源记录。资源记录是四元组
<Name, Value, Type, TTL>
TTL是生存时间,它决定了资源记录应当从缓存中删除的时间。在下面的例子中,我们省略TTL字段。Name和Value的值取决于Type:
·若Type = A,则Name是域名,Value是该主机名对应的IP地址。因此,一条类型为A的资源记录提供了标准的主机名到IP地址的映射。例如
<relay-05.nz.3134.com, 145.37.93.126, A>
就是一条A记录。
·若Type = NS,则Name是域名(如3134.com),而Value是知道如何获得该域中主机IP地址的权威DNS服务器的主机名。这个记录用于沿着查询链来路由DNS查询。例如
<3134.com, dns.3134.com, NS>
就是一条NS记录。
·若Type = CNAME,则Value是别名为Name的域名对应的规范主机名。该记录能够向查询的主机提供一个主机名对应的规范主机名,例如
<3134.com, relay-1a.ca.3134.com, CNAME>
就是一条CNAME记录。
·若Type = MX,则Value是别名为Name的邮件服务器的规范主机名。举例:
<oust.edu.cn, mail.oust.edu.cn, MX>
就是一条MX记录。MX记录允许邮件服务器主机名具有简单的别名。值得注意的是,通过使用MX记录,一个公司的邮件服务器和其它服务器(如Web服务器)可以使用相同的别名。为了获得邮件服务器的规范主机名,DNS客户应当请求一条MX记录;要获得其它服务器的规范主机名,DNS客户应当请求CNAME记录。

如果一台DNS服务器是用于某特定主机名的权威DNS服务器,那么该DNS服务器会有一条包含该主机名的A记录(即使不是,也可能在缓存中包含A记录)。如果服务器不是用于某主机名的权威服务器,那么该服务器包含一条NS记录,该记录提供了包含该主机名的域和权威服务器的主机名;它还包含一条A记录,提供权威服务器的主机名及其IP地址。
举例:设一台edu TLD服务器不是主机gaia.cs.umass.edu的权威DNS服务器,则该服务器将包含一条包括主机gaia.cs.umass.edu的域记录,如<umass.edu, dns.umass.edu, NS>;该edu TLD服务器还将包含一条类型A记录,如<dns.umass.edu, 128.119.40.111, A>,该记录将名字dns.umass.edu映射为一个IP地址。

DNS只有查询和响应两种报文,并且格式相同。DNS报文中各字段的语义如下:
前12个字节是报头区域,其中有几个字段。
第一个字段(标识符)占16位,用于标识查询。这个标识符会被复制到响应报文中,以便将请求与响应报文逐一匹配。
标志字段中含有若干标志:
查询 / 回答标志位(question / response)1位,指出报文是查询报文(0)还是回答报文(l)。
操作码(opcode)4位。0 表示标准查询;1 表示反向查询;2 表示服务器状态请求,3 ~ 15保留。
权威标志位(authoritative)1位,指示该服务器是否为所查询的目标主机的权威服务器(响应报文中有效)。
截断标志位(truncated)1位,值为1时表示响应已超过 512 字节并已被截断,只返回前 512 个字节。
期望递归标志位(recursion desired)1位,刻画客户在该DNS服务器没有某记录时是否希望它执行递归查询。
递归可用标志位(recursion available)1位,刻画该DNS服务器是否支持递归查询,在回答报文中有效。
保留字段(Z),必为零。
应答码字段(reply code)4位,表示是否出错。返回0表示正常,1表示请求报文格式错误,2表示域名服务器故障,3表示名字错误(只对权威服务器有意义:解析的域名不存在),4表示不支持查询该类型,5表示拒绝查询。6 ~ 15保留。

在该首部中,还有4个有关数量的字段,这些字段的无符号16位整数指出了在首部后的4类数据区域出现的数量。对于请求报文,只有第1个数量字段(问题)不为0。
·问题区域包含正在进行的查询信息。该区域包括:①名字字段,即正在被查询的主机名;②类型(type)字段,指出有关该名字的正被询问的问题类型,例如主机地址是与一个名字相关联(类型A)还是与某个名字的邮件服务器相关联(类型MX)。③类别(class)字段,IN——Internet;CS——CSNET类(已废弃);CH——CHAOS类;HS——Hesiod。

·在来自DNS服务器的回答中,回答区域包含了对最初请求的名字的资源记录。前面讲过每个资源记录中有Type、Value和TTL字段。在回答报文的回答区域中可以包含多条RR,因为一个主机名能够有多个IP地址。
·权威区域包含了其它权威服务器的记录。
·附加区域包含了其它有用的记录。例如,对于一个MX请求的回答报文的回答区域包含了一条资源记录,提供邮件服务器的规范主机名。又例如,该附加区域包含一个类型A记录,提供用于该邮件服务器的规范主机名的IP地址。

使用nslookup程序能够从本机直接向指定的DNS服务器发送一份DNS查询报文。对于多数Windows和UNIX平台,nslookup程序是可用的:打开终端,键入nslookup即可。调用nslookup后,你能够向任何DNS服务器(根、TLD或权威)发送DNS查询。收到响应报文后,nslookup将显示包括在该回答中的记录(以人类可读的格式)。还可以访问允许远程应用nslookup的许多Web站点之一(搜索“nslookup”)。
例如:
nslookup www.google.com a.root-servers.net
令根服务器解析www.google.com。还可以指定顶域服务器、二级域名服务器或本地域名服务器进行解析。

假设要创建一个名为Network Utopia的新创业公司。首先要做的便是注册域名networkutopia.com。注册登记机构(registrar)是一个商业实体,它确保域名的唯一性,将域名输入DNS数据库,并收取费用。1999年以前,唯一的注册登记机构是Network Solution,它独家经营对com、net和org域名的注册。但是现在有许多注册登记机构争抢客户,Internet名字和ICANN向各种注册登记机构授权。在http://www.internic.net 上可以找到授权的注册登记机构的列表。

向注册登记机构注册域名时,需要提供你的基本和辅助权威DNS服务器的主机名和IP地址。假定它们是dnsl.networkutopia.com和dns2.networkutopia.com及212.212.212.1和212.212.212.2。对提供的每台权威DNS服务器,注册登记机构确保将一条NS类型和一条A类型的记录输入TLD com服务器。对用于networkutopia.com的基本权威服务器,该注册登记机构将两条资源记录插入该DNS系统中:
<networkutopia.com, dns1.networkutopia.com, NS>
<dns1.networkutopia.com, 212.212.212.1, A>

你还必须确保用于Web服务器www.networkutopia.com 的A记录和用于邮件服务器mail.networkutopia.com的MX记录被输入你的权威DNS服务器中(如果需要提供邮件服务)。如今,DNS服务器中的内容常常是静态配置的,例如系统管理员会创建好配置文件。DNS协议中也添加了更新(UPDATE)选项,允许通过DNS报文增删数据库内容。

一旦完成所有这些步骤,人们就能够访问你的Web站点,并向公司的雇员发送电子邮件。

下面再来看一个例子,回顾我们已经学到的DNS的知识。
假定在澳大利亚的Alice要访问www.networkutopia.com的Web页面。
她的主机首先向本地DNS服务器发送请求。
该本地服务器联系一台TLD com服务器(若TLD com服务器的地址未缓存,则本地DNS服务器必须与根服务器联系)。该TLD服务器包含前面列出的NS和A资源记录,因为注册登记机构将它们插入了所有的TLD com服务器。
该TLD com服务器向Alice的本地DNS服务器发送一个回答,该回答包含了这两条资源记录。
该本地DNS服务器则向212.212.212.1发送一个DNS查询,请求对应于www.networkutopia.com的类型A记录。该记录提供了所希望的Web服务器的IP地址,如212.212.71.4,本地DNS服务器将该地址回传给Alice的主机。
Alice的浏览器此时能够向主机212.212.71.4发起一个TCP连接,并在该连接上发送一个HTTP请求。

一种针对DNS服务的攻击是分布式拒绝服务(DDoS)带宽洪水攻击(见1.6节):攻击者试图向DNS根服务器发送大量的分组,使大多数合法DNS请求得不到响应。一次对根服务器的DDoS大规模攻击发生在2002年10月21日。攻击者利用一个僵尸网络向13组根服务器都发送了大批的ICMP ping报文(见5.6节,现在知道ICMP分组是特殊的IP数据报就可以了)。幸运的是,攻击的损害很小,对Internet体验几乎没有影响。攻击者的确成功将大量分组指向了根服务器,但许多ICMP ping报文被DNS根服务器的分组过滤器阻挡了。此外,大多数本地DNS服务器缓存了顶级域名服务器的IP地址,使得这些请求不会被千里迢迢发送到DNS根服务器。
对DNS的潜在更为有效的DDoS攻击是:向顶域服务器发送大量的DNS请求。过滤指向非根服务器的DNS请求更为困难,并且顶域服务器不像根服务器那样容易绕过。但是这种攻击也可以通过本地DNS服务器中的缓存部分缓解。

DNS还会以其它方式被攻击。在中间人攻击(man-in-the-middle attack)中,攻击者截获来自主机的请求并返回伪造的回答。在DNS污染(DNS poisoning)攻击中,攻击者向一台DNS服务器发送伪造的回应,诱使其在缓存中存储伪造的记录。这些攻击中的任意一种,都能将Web用户重定向到攻击者的Web站点。然而,这些攻击难以实现,因为它们要求截获分组或设法降低服务器的响应速率。总之,DNS已经具备可观的健壮性(robustness)。至今还没有一次攻击成功破坏大范围(例如遍及数个主要国家和地区)的DNS服务。
2.5 P2P应用举例:文件传输

假设一个网络里有一台服务器和若干台客户端,部分客户端需要同一个文件。如果采用传统的C-S结构,那么服务器要对每台需要此文件的计算机都进行一次传输;而如果采用P2P方式,服务器可以先向一台机传输文件,之后所有存储了此文件(或文件的一部分)的终端(包括服务器本身)都可以通过自己的上传通道将文件传输给其它终端,大大加快了总传输速率。下图是一个采用C-S结构和P2P结构进行分发的总耗时对比的例子。

目前在互联网流量中,P2P文件分发占据了最大的份额,比WWW应用所占的比例大得多。因此单纯从流量的角度看,P2P文件分发应当是互联网上最重要的应用。现在P2P文件分发不仅传送音频,还传送视频、软件和图像。

最早使用P2P工作方式的是Napster,它由1999年美国东北大学的新生Shawn Fanning所写。利用这个软件就可通过互联网免费下载各种MP3音乐。Napster的出现使MP3成为网络音乐事实上的标准。
Napster能够搜索音乐文件。所有音乐文件的索引信息都集中存放在Napster目录服务器中。目录服务器起着索引的作用。使用者只要查找目录服务器,就可知道应从何处下载需要的MP3文件。在2000年,Napster成为互联网上最流行的P2P应用,并占据互联网上的通信量中相当大的比例。
这里的关键是:运行Napster的所有用户,都必须及时向Napster的目录服务器报告自己已经存有哪些音乐文件。Napster目录服务器利用这些用户信息建立一个动态数据库,集中存储了所有用户的音乐文件信息(即对象名和相应的IP地址)。当用户想下载MP3文件时,就向目录服务器发出查询(这个过程仍是传统的客户-服务器方式),目录服务器检索出结果后向用户返回存放这一文件的计算机IP地址,于是这个用户就可以从中选取一个地址下载想要的MP3文件(下载过程就是P2P方式)。可以看出,Napster的文件传输是分散的(P2P方式),但文件的定位则是集中的(C-S方式)。
这种集中式目录服务器的最大缺点就是可靠性差,而且会成为其性能的瓶颈(尤其是在用户数非常多的情况下)。更为严重的是:这种做法侵犯了唱片公司的版权。虽然Napster网站并没有直接非法复制任何MP3文件(Napster网站不存储任何MP3文件,因而并没有直接侵犯版权),但法院还是判决Napster属于“间接侵害版权”,因此在2000年7月底Napster网站就被迫关闭了。

BitTorrent是一种用于文件分发的常用P2P协议。用BitTorrent术语来讲,参与一个特定文件分发的所有对等方的集合称为洪流(torrent)。在一个洪流中的对等方彼此下载等长(如256 KB)的文件块(chunk)。一个对等方首次加入一个洪流时,没有文件块。随着时间推移,它累积了越来越多的块。当它下载块时,也为其它对等方上载多个块。获得整个文件后,可以选择离开洪流或继续向其它对等方上载文件块,也可在下载完文件的部分块以后就离开洪流,以后重新加入之。

BitTorrent是一个相当复杂的协议,我们仅描述它最重要的机制。
每个洪流具有一个基础设施结点,称为追踪器(tracker)。当一个对等方加入某洪流时,它向追踪器注册(登记)自己,并周期性地通知追踪器它仍在该洪流中。追踪器凭此跟踪洪流中的对等方。一个洪流可以具有几个到几千个以上的对等方。

当一个新的对等方A加入该洪流时,追踪器随机选择对等方的一部分(比如30个),并将它们的IP地址传回。A便拥有了记录了对等方的列表,并试图与该列表上的所有对等方创建并行的TCP连接。我们称所有这样与A成功创建TCP连接的对等方为“邻近对等方”(neighboring peers)。之后,某些对等方可能离开,新的对等方可能试图与A创建TCP连接。

不同的对等方通常具有一个文件的不同部分。A周期性地(经TCP连接)询问每个邻近对等方所具有的块。如果A具有n个不同的邻居,它将获得n个块列表。有了这个信息,A试图获取当前还没有的块(仍通过TCP连接)。

最稀缺优先(rarest first)的思路是:优先尝试获取那些在已建立连接的对等方中副本最少的块。这样,最稀缺的块将尽快在网络中重新分发,于是每个块在洪流中的副本数量趋于均衡。如果不使用此方法,一旦拥有最稀有文件块的对等方全都退出了洪流,就会影响A对所缺文件块的收集。

为了决定先响应哪个请求,BitTorrent使用了一种巧妙的对换算法。其基本思想是:根据邻近结点当前的传输速率给出优先权。例如,每隔1秒测定一次速率并选出4个给自己传输数据最快的邻近对等方,这4个对等方的当前状态称为疏通(unchoked,无障碍);每隔30秒随机选择另一邻近结点并向其发送文件块。我们将这个被随机选择的对等方记为B。因为A正向B发送数据,它也可能成为最快把数据传给B的前4位上载者之一,于是B也开始向A发送数据。如果B向A发送数据的速率足够高,B接下来也能成为给A传输数据最快的上载者。这就使对等方能够彼此协调收发速率。随机选择新的对等方也使其它用户不被“饿着”,也有机会得到块。除了这5个对等方,所有其它相邻对等方均被阻塞(choked),即它们不能从A接收到任何块。
BitTorrent还有一些机制没有在这里讨论,包括分片(pieces)、流水线、随机优先选择、残局模式(endgame mode)和反怠慢(anti-snubbing)。

这种激励机制常被称为“一报还一报”(tit-for-tat),不过它也是能被绕过的。但无论如何,BitTorrent的生态系统取得了广泛成功。如今,亿万对等方在无数的洪流中积极地共享文件。如果BitTorrent不采用此种机制(或其变种),它将很可能不复存在,因为大多数人会选择只吃饭不干活,下完东西就溜,而不通过上传为别人做种。

设有n台主机从服务器下载若干个大文件,总长度为S。主机i与互联网连接的链路的理论上传和下载速率分别为u_i和d_i。
如果采用传统的C/S结构,则:
·服务器为每台主机分发全部所需文件的时间不少于nS/u_s,其中u_s为服务器将数据上传到网络的最高速率。
·如果下载最慢的主机的下载速率为d_min,则该主机下载所需文件花费的时间不少于F/d_min。
因此,所有主机都下载完总大小为S的文件需要的最少时间是
T_CS=max⁡(nS/u_s , S/d_min )
如果采用P2P方式,则:
·服务器将文件发送给第一台主机的花费的时间不少于S/u_s。
·下载最慢的主机将所需文件下载完毕花费的时间不少于S/d_min。
·文件全部分发给n台主机花费的时间不少于nS/u_TOTAL。其中u_TOTAL是参与上传的全部主机的速率之和。显然,u_TOTAL是一个理想的最大值。文件总是要在开始时先由服务器单独分发给一些主机,得到文件(或其一部分)后的主机再分发给其它需要这些文件的主机,在这样的过程中逐渐令上传总速率接近理论最大值u_TOTAL。
因此,所有主机都下载完总大小为F的文件需要的最少时间是
T_P2P=max⁡(S/u_s , S/d_min , nS/u_TOTAL )

分布式散列表(DHT)也是P2P的应用,它是一种简单的数据库,分布在一个P2P系统的多个对等方上,由大量对等方共同维护。DHT得到了广泛实现(如在BitTorrent中),并成为大量研究的主题。
DHT在BT中主要用于迅速找到所需的文件。本质上说,DHT需要存储的结构就是计算机科学中非常基本的一种结构:key-value对。在DHT中,每对key和value分别是资源名(如电影名或歌曲名)、存放资源内容的结点的IP地址(可能还有端口号)。每个结点代表在同一个洪流中的一个对等方。

细心的读者可能会联想到前面讨论的DNS。DNS根据主机的域名来查找其IP地址,这和P2P有相似之处。但是主机的域名是结构化的,因此域名服务器可以划分为几种不同的级别(如根服务器等)便于查找。P2P系统则不同,其资源名是非结构化的。因此不能套用DNS的那种查找方法。
作为对比,前面已经讲过,Napster在一个集中式目录服务器中构建的查找数据库虽然很简单,但性能上却有瓶颈。在P2P系统中,应怎样构建分布式数据库?让每个对等方都拥有所有对等方IP地址的列表开销过大,是不可行的。让所有成对出现的 <资源名,IP地址> 键值对随机地分散到各对等方也是不可行的。因为在一个对等方中没有查找到结果时,就不得不访问另外的对等方进行查找,最坏情况下直到所有的对等方都查找完毕,才能找到需要的IP地址或确认要查找的内容不存在。这将使查找次数过大,也不可行。
基于DHT的具体算法已有不少,如Chord,Pastry,CAN(Content Addressable Network),以及Kademilia等。下面简单介绍广泛使用的Chord算法,它由MIT于2001年提出。
DHT利用散列函数H,把资源名K及其存放的结点IP地址N都分别映射为资源名标识符K_x和结点标识符N_y。即:
H(K)=K_x,H(N)=N_y,x, y∈Z
如果哈希(Hash)函数H设计得较为优秀,那么映射得到的标识符能尽量均匀而稀疏地分布在Chord环上。
首先把Chord环用若干个点均匀划分,将这些点编号。映射的规则是:
(1)N_x映射到环上的一个点,这个点的编号就是x。
(2)K_x映射到与x最接近的下一个N_y。有两点要注意:
·规则(2)是指:从点x开始,按顺时针方向沿环遇到的下一个N_y。如果环上恰好有一个N_x与K_x都具有相同的下标,则K_x映射到此N_x。
·允许不同的K_x映射到同一个N_y。

在查找时,当客户端(对应某个结点N)给出资源名称K,哈希函数H就把K转换成H(K)=K_x,然后通过哈希表找到对应的N_y,再通过N_y对应的结点记录的全体IP地址去获取需要的资源。
每个资源由Chord环上与其标识符值最接近的下一个结点提供服务。我们再强调一下,Chord环并非实际的网络。在Chord环上相邻的结点,在地理上很可能相距非常远。

环上的每一个结点都要维护两个指针变量,分别指向其后继和前驱结点。一个结点沿逆时针、顺时针方向指向的下一个结点分别为其前驱和后继结点。当有对等方加入和退出时,相应结点的前驱和后继必须及时更新。
如要在这样的Chord环上查找资源,则对任何一个结点,只要从其后继结点一个个地查找下去,一定可以查找到所需资源或确定该资源在此洪流中不存在。这种顺序查找的时间复杂度为O(n),为环上的总结点数。

为了加速查找,我们为每个结点引入指针表。
假设N_x是任意一个结点,哈希函数H把资源名称转换为m位二进制长度的哈希。那么,结点N_x的指针表需要记录m个指针,分别指向点x+20,x+21,…,x+2^(m-1)(全部要模m)沿顺时针方向的下一个结点。
使用指针表以后,当同一个洪流中的某个结点N要查找资源K时,先使用哈希函数计算H(K)=K_x。
因为记录了每个资源K_x的全部存储位置的结点总是沿顺时针方向尽量接近点x的结点,所以N可以先在自己的指针表中查找最接近于点x的结点N_y而不用访问其它对等方,然后交由N_y继续类似的查找。
这种查找方法类似于二分查找。根据确定指针表应当记录的每一项的规则,不难发现,获得存储了资源K的全部IP地址的时间复杂度降低到O(log⁡n)。

在P2P网络中,对等方可能相当频繁地加入或退出系统,这就需要很好地维护这个分布式数据库(维护各结点的指针和指针表),而这种维护的工作量可能会很大。当对等方数量非常大时,究竟采用何种查询机制更加合理,则需要根据具体情况来确定。
2.6 视频串流和CDN
讨论视频串流之前,先简单回顾一下视频。视频是一系列的图像,通常以恒定帧率(CFR,如23.976 fps或25 fps或30 fps)或可变帧率(VFR)来展现。一帧未压缩的图像是二维的像素阵列,每个像素包含表示亮度和颜色的一些比特。视频能够被(无损或有损)压缩,我们用比特率来衡量视频质量。现有的压缩算法能够将一个视频压缩成所希望的任何比特率。比特率越高,图像质量越好。通常,视频的比特率随时间而变化。

压缩的网络视频的比特率范围可以是很低的100到200 kbps,也可以超过3到10 Mbps。为了连续不断地播放多媒体内容,网络必须为流式应用提供平均吞吐量,不能低于视频的比特率。通常,网站准备了相同视频的多个版本,它们画质不同。用户根据可用带宽决定观看哪个版本。

在HTTP流中,视频只是存储在HTTP服务器中的一个普通的文件,每个文件有特定的URL。当用户要观看视频时,客户与服务器创建一个TCP连接并发送对该URL的HTTP GET请求。服务器凭借底层网络协议和尽可能快的速率,在一个HTTP响应报文中发送该视频。在客户一侧,字节被保存在应用缓存中。一旦缓存中的字节数超过预设的阈值,应用程序就开始播放。流式视频应用程序周期性地从缓存中抓取帧,解压并输出,同时缓存视频后续部分的帧。

尽管HTTP串流在实践中已经得到广泛部署(例如YouTube初期),但它具有严重缺陷,即所有客户接收到的都是相同编码的视频,尽管不同情况下可用的带宽大小不同。于是,经HTTP的动态适应性串流(Dynamic Adaptive Streaming over HTTP,DASH)被发明出来。在DASH中,视频编码为几个版本,每个版本具有不同的比特率。客户动态请求不同版本且长度为若干秒的视频段数据块。当可用带宽较大时,选择高码率的块;否则,选择低码率的块。客户用HTTP GET请求报文一次选择—个不同的块。

DASH允许客户使用不同的以太网接入速率流式播放具有不同编码速率的视频。如果端到端带宽在会话过程中改变,DASH允许客户适应可用带宽。这对移动用户特别重要,当移动用户随着地理位置的不同而自动连接到附近的基站时,网络带宽会波动。使用DASH时,每个视频版本存储在HTTP服务器中,用不同的URL标识。HTTP服务器也有一个告示文件(manifest file),包含每个版本的URL及其比特率。客户首先请求该告示文件,获得不同版本的信息。然后,通过在HTTP GET请求报文中对每块指定一个URL和一个字节范围,一次选择一块。在下载块的同时,客户也测量接收带宽并通过算法选择下次请求的块。DASH允许客户自由地在不同的质量等级之间切换。

对于一个Internet视频公司,提供流式视频服务最为直接的方法是建立单一的大规模数据中心存储并直接向全世界传输流式视频。但是这种方法存在三个问题。
首先,如果客户远离数据中心,分组将跨越许多通信链路并通过许多ISP,某些ISP可能位于不同的大洲。如果这些链路之一提供的吞吐量小于视频码率,端到端吞吐量也将小于码率,给用户带来恼人的停滞。发生此情况的可能性随着端到端路径中链路数量的增加而增加。第二个缺陷是热门视频会经过相同的通信链路发送许多次。这不仅严重浪费带宽,公司也需向ISP支付高昂的费用。第三个问题是如果该数据中心故障,或其通向Internet的链路崩溃,公司将无法分发任何视频流。

目前,几乎所有主要的视频流公司都利用内容分发网络(Content Distribution Network,CDN)管理分布在多个地理位置上的服务器,在它的服务器中存储视频(和其他类型的Web内容,包括文档、图片和音频)的副本,并试图将每个用户请求定向到一个将提供最好的用户体验的CDN位置。CDN可以是专用的,即由内容提供商自己所拥有:例如,谷歌的CDN分发YouTube视频和其他类型的内容;也可以是第三方CDN:Akamai、Limelight和Level-3都运行第三方CDN。

CDN通常采用两种不同的服务器安置原则:
·深入(Enter Deep)。该原则由Akamai首创:通过在遍及全球的接入ISP中部署服务器集群来深入到ISP的接入网(见1.3节)中。Akamai在至少1700个位置这样部署集群。其目标是靠近端用户,通过减少端用户和CDN集群之间的链路和路由器的数量,从而改善时延和吞吐量。因为高度分散,维护和管理集群的任务具有一定难度。
·邀请做客(Bring Home)。该原则由Limelight和许多其他CDN公司采用:通过在少量(例如10个)关键位置建造大集群来邀请ISP“做客”,不将集群放在接入ISP中,而通常将它们的集群放置在Internet交换点(IXP)。与深入设计原则相比,邀请做客设计通常产生较低的维护和管理开销,但可能导致端用户的较高时延和较低吞吐量。

一旦CDN的集群准备就绪,它就可以跨集群复制内容。CDN一般不将每个视频的副本放置在每个集群中,因为某些视频很少观看或仅在某些国家流行。如果客户向一个未存储该视频的CDN集群请求某视频,则集群检索该视频(从某中心仓库或另一个集群),向客户流式传输视频时的同时在本地存储一个副本。类似于Internet缓存(参见2.2节)。当某集群存储器变满时,它删除不经常请求的视频。

现在讲解CDN操作的细节。当用户主机中的一个浏览器指令检索一个特定的视频(由URL标识)时,CDN必须截获该请求,以便能够:①确定此时适合用于该客户的CDN服务器集群;②将客户的请求重定向到该集群的某台服务器。

大多数CDN利用DNS来截获和重定向请求。假定内容提供商NetCinema雇佣了第三方CDN公司KingCDN向其客户分发视频。在NetCinema的Web网页上,每个视频都被指派了URL,该URL包括了字符串“video”以及该视频本身的标识符。例如,《变形金刚7》的URL是http://video.netcinema.com/6Y7B23V。接下来发生6个事件:
1)用户访问NetCinema。
2)用户访问http://video.netcinema.com/6Y7B23V时,用户主机发送一个对于video.netcinema.com的DNS请求。
3)用户的本地DNS服务器(LDNS)将该DNS请求中继到一台用于NetCinema的权威DNS服务器,该服务器观察到主机名video.netcinema.com中的字符串“video”。为了将该DNS请求移交给KingCDN,NetCinema权威DNS服务器并不返回一个IP地址,而是向LDNS返回一个KingCDN域的主机名,如al105.kingcdn.com。
4)从这时起,DNS请求进入了KingCDN专用的DNS基础设施。用户的LDNS发送对all05.kingcdn.com的DNS请求,KingCDN的DNS系统最终向LDNS返回KingCDN内容服务器的IP地址。即:KingCDN的DNS系统指定了CDN服务器,客户将能够从这台服务器接收到它的内容。
5)LDNS向用户主机转发内容服务CDN结点的IP地址。
6)一旦客户收到KingCDN内容服务器的IP地址,它与具有该IP地址的服务器创建了一条直接的TCP连接,并且发出对该视频的HTTP GET请求。如果使用了DASH,服务器将首先向客户发送具有URL列表的告示文件,每个URL对应视频的每个版本,并且客户将动态地选择来自不同版本的块。

CDN部署的核心是集群选择策略(cluster selection strategy),即动态地将客户定向到CDN中的某个服务器集群或数据中心的机制。如我们刚才所见,经过客户的DNS查找,CDN得知了该客户的LDNS服务器的IP地址。在得知该IP地址之后,CDN需要基于该IP地址选择一个适当的集群。CDN一般采用专用的集群选择策略。

一种简单的策略是指派客户到地理上最为邻近的集群。商用地理位置数据库(比如Quova和Max-Mind)记录了LDNS的IP地址对应的地理位置。当从特定的LDNS接收到DNS请求时,CDN为客户选择地理上最接近的集群。这样的解决方案通常具有相当不错的效果。但对于某些客户,效果则比较差:考虑网络路径的长度或跳数,地理最邻近的集群未必是延迟最小的集群。此外,一种所有基于DNS的方法都内在具有的问题是,某些中断配置使用位于远地的LDNS。在这种情况下,LDNS位置可能远离客户的位置。此外,这种简单的策略忽略了时延和带宽的波动,总是为特定位置的客户指派相同的集群。

为了基于当前流量条件为客户选择最好的集群,CDN会对其集群和客户之间的时延和丢包性能执行周期性的实时测量。例如,CDN能够让每个集群周期性地向全世界的LDNS发送探测分组(ping报文、DNS请求等)。但出于防止网络攻击等原因,许多LDNS会直接丢掉这种数据包。

下面来看Google的网络基础设施,作为CDN的一个实例。
为了支持谷歌的巨量云服务:搜索、Gmail、日程表、YouTube视频、地图、文档和社交网络……,谷歌已经部署了一个遍布全球的专用网和CDN基础设施。谷歌的CDN基础设施具有三个等级的服务器集群:
·14个大型数据中心,其中8个位于北美,4个位于欧洲,2个位于亚洲,每个数据中心至少具有10万台的服务器。这些数据中心负责服务于动态的(并且经常是个性化的)内容,包括搜索结果和Gmail报文。
·分布全球的一些IXP中,每个大约包含50个集群,每个集群由不少于100~500台服务器组成。这些集群服务于静态内容,包括YouTube视频。
·在一些接入ISP中,每个包含数以百计的“深入(enter-deep)”集群。一个集群通常由一个机架上的数十台服务器组成。它们负责TCP分岔(见3.7节)并服务于静态内容,包括搜索结果的静态Web网页。
所有这些数据中心和集群与谷歌自己的专用网连接在一起。当用户进行搜索时,搜索请求常常先经过本地ISP发送到邻近的“深入服务器”缓存中,从这里检索静态内容;同时,邻近的缓存也将该静态内容提供给客户,并经谷歌的专用网将请求转发给大型数据中心,获得个性化的搜索结果。对于某YouTube视频,该视频本身可能来自一个“邀请坐客(bring-home)”服务器缓存,而围绕该视频的Web网页部分可能来自邻近的“深入服务器”缓存,围绕该视频的广告来自数据中心。总的来说,除了本地ISP的那部分,谷歌云服务在很大程度上是由独立于公共Internet的网络基础设施提供的。
2.A FTP与TFTP
文件传输协议(File Transfer Protocol,FTP)是互联网上使用最广泛的文件传送协议。FTP提供交互式的访问,允许客户指明文件的类型与格式(如指明是否使用ASCII码),并允许文件具有存取权限(如访问文件的用户必须经过授权,并输入有效的口令)。FTP屏蔽了各计算机系统的细节,因而适合于在异构网络中任意计算机之间传送文件。
在互联网发展早期,FTP流量约占全部互联网流量的1/3,电子邮件和DNS所产生的通信量还小于FTP所产生的通信量。到了1995年,WWW的通信量才首次超过了FTP。

基于TCP的FTP和基于UDP的简单文件传送协议TFTP都是文件共享协议中的一大类,它们总是复制整个文件:若要存取一个文件,就必须先获得一个本地的文件副本;如果要修改文件,只能先修改本地的副本,再将修改后的副本传回。

文件共享协议中的另一大类是联机访问(on-line access),即在线访问,允许多个程序同时存取一个文件。和数据库不同,用户不需要调用一个特殊的客户进程,而是由操作系统提供对远地共享文件进行访问的服务,如同访问本地文件一样。这就使用户可以用远程文件直接作为输入和输出来运行任何应用程序,而操作系统中的文件系统则提供对共享文件的透明存取。透明存取的优点是:将原来用于处理本地文件的应用程序用来处理远地文件时,不需要对该应用程序作明显的改动。

网络文件系统NFS(Network File System)也属于文件共享协议。NFS最初是在UNIX环境实现文件和目录共享的。NFS可使本地计算机共享远地的资源,就像这些资源在本地一样。NFS是SUN公司在TCP / IP网络上创建的,因此目前主要应用在TCP / IP网络上。然而现在NFS也可在OS / 2,Windows和NetWare等操作系统上运行。与FTP不同,NFS还没有成为互联网的正式标准。NFS允许应用进程打开一个远地文件,并能在该文件的某一个特定的位置上开始读写数据。这样,NFS只复制一个大文件中的一个很小的片段,而不需要复制整个大文件。限于篇幅,这里不讨论NFS的详细工作过程。

初看起来,在两台主机之间传送文件是很简单的事情。其实这往往非常困难。原因是众多的计算机厂商研制出的文件系统多达数百种,且差别很大。经常遇到的问题有:
(1) 计算机存储数据的格式不同。
(2) 文件的目录结构和文件命名的规定不同。
(3) 对于相同的文件存取功能,操作系统使用的命令不同。
(4) 访问控制方法不同。
FTP只提供文件传送的一些基本服务。它使用TCP可靠的运输服务。FTP的主要功能是:减少或消除在不同操作系统下处理文件的不兼容性。
FTP使用C-S结构。一个FTP服务器进程可同时为多个客户进程提供服务。FTP的服务器进程由两大部分组成:一个主进程,负责接受新的请求;若干个从进程,负责处理单个请求。
主进程的工作步骤如下:
(1) 打开21端口,使客户进程能够连接上。
(2) 等待客户进程发出连接请求。
(3) 启动从属进程处理客户请求。从进程在请求处理完毕后即终止,但从进程在运行期间还可能根据需要创建一些子进程。
(4) 回到等待状态,继续接受其它客户进程发来的请求。
主进程与从属进程的处理是并发进行的。

文件传输时,FTP的客户和服务器之间要建立两个并行的TCP连接:控制连接和数据连接。
控制连接在会话期间保持打开,FTP客户所发出的传送请求,通过控制连接发送给服务器端的控制进程(主进程),但控制连接并不用来传送文件。实际用于传输文件的是数据连接。服务器端的控制进程在接收到FTP客户发送来的文件传输请求后就创建数据传送进程(从进程)和数据连接,用来连接客户端和服务器端的数据传送进程。数据传送进程实际完成文件的传送,在传送完毕后关闭数据连接并结束运行。由于FTP使用了分离的控制连接,因此FTP的控制信息是“带外”(out of band)传送的。
使用两个独立的连接的主要好处是:协议更简单、更容易实现,同时在传输文件时还便于利用控制连接对文件的传输进行控制(例如,客户请求终止传输)。

FTP中,若工作在主动模式(PORT方式)下,则客户端从任意的非熟知端口p(> 1023,见3.2节)和服务器的21端口连接,服务器收到命令后,主动使用20端口连接客户端的p+1端口用于数据连接。使用不同端口号使得数据连接与控制连接不会混乱。
另一种FTP连接方式是被动方式,或者叫做PASV,当客户端通知服务器它处于被动模式时才启用。需要传输数据时,客户端从端口p发出命令至服务器的21端口。服务器将需要建立数据连接的IP和监听端口(动态端口)x发回给客户端。客户端的p+1端口与服务器的x端口建立连接,相当于服务器被动接受客户端的数据连接建立请求。在Internet选项中可以启用“使用被动FTP”。

TCP / IP协议族(protocol suite)中还有一个很小且易于实现的简单文件传送协议TFTP(Trivial File Transfer Protocol)。TFTP的版本2是互联网的正式标准。虽然TFTP也使用C-S结构,但它使用UDP,因此需要有自己的纠错措施。TFTP只支持文件传输而不支持交互。TFTP没有一个庞大的命令集,没有列目录的功能,也不能对用户进行身份鉴别。

TFTP的主要优点有两个。第一,TFTP可用于UDP环境。例如,当需要将程序或文件同时向许多机器下载时,往往需要使用TFTP。第二,TFTP代码内存占用较少。这对较小的计算机或特殊用途的设备是很重要的。这些设备不需要硬盘,只需要固化了TFTP、UDP和IP的小容量ROM即可。当接通电源后,设备执行ROM中的代码,在网络上广播一个TFTP请求。网络上的TFTP服务器就发送响应,其中包括可执行二进制程序。设备收到此文件后将其放入内存,然后开始运行程序。这种方式增加了灵活性,也减少了开销。

TFTP的主要特点是:
(1) 每次传送的数据报文中有512字节的数据,但最后一次可不足512字节。
(2) 数据报文按序编号,从1开始。
(3) 支持ASCII码或二进制传送。
(4) 可对文件进行读或写。
(5) 使用很简单的首部。

TFTP在发送完一个文件块后就等待对方的确认,确认时应指明所确认的块编号。发完数据后在规定时间内收不到确认就要重发PDU。接收方若在规定时间内收不到下一个文件块,也要重发确认PDU。这样就可保证文件的传送不致因某份数据报的丢失而宣告失败。
在开始工作时,TFTP客户进程发送一个读(写)请求报文给TFTP服务器进程,端口为69。TFTP服务器进程要选择一个新的端口和TFTP客户进程进行通信。若文件长度恰好为512字节的整数倍,则在文件传送完毕后,还必须在最后发送一个只含首部而无数据的数据报文。若文件长度不是512字节的整数倍,则最后传送数据报文中的数据字段一定不满512字节,这正好可作为文件结束的标志。
2.B TELNET
TELNET是一个简单的远程终端协议,它也是互联网的正式标准。用户用TELNET就可在其所在地通过TCP连接注册(登录)到远地的另一台主机上(使用主机名或IP地址)。TELNET能将用户的键盘输入传到远地主机,也将远地主机的输出通过TCP连接返回到用户屏幕。这种服务是透明的,因为用户感觉键盘和显示器好像直接连接到远地主机。因此,TELNET又名终端仿真协议。TELNET并不复杂,以前应用得很多。现在由于计算机的功能越来越强,用户已较少使用TELNET了。
TELNET也使用客户服务器方式。在本地系统运行TELNET客户进程,而在远地主机则运行TELNET服务器进程(端口23)。和FTP的情况相似,服务器中的主进程等待新的请求,并产生从属进程来处理每一个连接。
TELNET能够适应许多计算机和操作系统的差异。例如不同的系统用不同的方式刻画一行的结束(CR、LF、CRLF)。又如,在中断一个程序时,许多系统使用Ctrl+C(^C),但也有系统使用ESC。为了适应这种差异,TELNET定义了数据和命令应怎样通过互联网。这些定义就是所谓的网络虚拟终端NVT(Network Virtual Terminal)。下图说明了NVT的意义。客户软件把用户的击键和命令转换成NVT格式,并送交服务器。服务器软件把收到的数据和命令从NVT格式转换成远地系统所需的格式。向用户返回数据时,服务器把远地系统的格式转换为NVT格式,本地客户再从NVT格式转换到本地系统所需的格式。

NVT的格式定义很简单。所有的通信都使用8位一个字节。在运转时,NVT使用7位ASCII码传送数据,而当高位置1时用作控制命令。ASCII码共有95个可打印字符(如字母、数字、标点符号)和33个控制字符。所有可打印字符在NVT中的意义和在ASCII码中一样。但NVT只使用了ASCII码的控制字符中的几个。此外,NVT还定义了两字符的CRLF为标准的行结束控制符。当用户键入回车按键时,TELNET的客户就把它转换为CRLF再进行传输,而TELNET服务器要把CRLF转换为远地机器的行结束字符。
TELNET的选项协商(Option Negotiation)使TELNET客户与服务器可商定使用更多的终端功能,协商的双方是平等的。
现在,许多用户现在更愿意采用SSH协议而不是Telnet,因为在Telnet连接中发送的数据(包括密码)是没有加密的,使得Telnet易于受到窃听。
2.C 搜索
在Web中用来进行搜索的工具叫做搜索引擎(search engine)。搜索引擎的种类很多,但大体上可分为两类,即全文检索搜索引擎和分类目录搜索引擎。
全文检索搜索引擎是一种纯技术型的检索工具。它的工作原理是:通过搜索软件,例如蜘蛛(spider)或爬虫(crawler),到互联网的各个网站收集信息,找到一个网站后,从这个网站再链接到另一个网站,像蜘蛛爬行一样。然后按照一定的规则,建立一个很大的在线索引数据库供用户查询。用户在查询时只要输入关键词,就从已经建立的索引数据库里进行查询(并不是实时地在互联网上检索到的信息)。因此很可能有些查到的信息已经是过时已久的。建立这种索引数据库的网站必须定期更新维护数据库,但不少网站的维护很不及时,因此对查找到的信息一定要注意其发布时间。现在全球最大、最受欢迎的全文检索搜索引擎就是Google。谷歌提供的主要的搜索服务有:网页、图片、视频、地图、新闻、购物、博客、论坛、学术、财经搜索等。应全球用户的需求,谷歌在世界各地建立数据中心。至2013年底,谷歌的数据中心在全球共设有12处。大多数数据中心的业主基于信息安全考虑,极少透露其数据中心的信息及内部情形。另外两个常用的全文检索搜索引擎分别是Bing和百度。

分类目录搜索引擎并不采集网站的任何信息,而是利用各网站向搜索引擎提交网站信息时填写的关键词和网站描述等信息,经过审核编辑后,如果认为符合网站登录的条件,则输入到分类目录的数据库中,供网上用户查询。因此,分类目录搜索也叫做分类网站搜索。分类目录的好处就是用户可根据网站设计好的目录有针对性地逐级查询所需要的信息,查询时不需要关键词,只需按照分类(先找大类,再找下面的小类),因而查询的准确性较好。但分类目录查询的结果并不是具体的页面,而是被收录网站主页的URL地址,因而所得到的内容就比较有限。相比之下,全文检索可以检索出大量的信息(一次检索的结果是几百万条,甚至是千万条以上),但缺点是查询结果不够准确,往往是罗列出了海量的信息(如上千万个页面),使用户无法迅速找到所需的信息。在分类目录搜索引擎中最著名的就是雅虎。国内著名的分类搜索引擎有雅虎中国、新浪、搜狐、网易等。

目前出现了垂直搜索引擎(Vertical Search Engine),它针对特定领域、特定人群或特定需求提供搜索服务。垂直搜索也是通过关键字搜索的,但返回的是特定行业相关的信息、消息、条目等。例如,对买房的人讲,他希望查找的是房子的具体信息(如面积、地点、价格等),而不是有关住房供求的一般性的论文或新闻、政策等。热门的垂直搜索行业有:购物、旅游、汽车、求职、房产、交友等。还有一种元搜索引擎(Meta Search Engine),它把用户的检索请求发送到多个独立的搜索引擎上搜索,并把检索结果集中统一处理,以统一的格式提供给用户,是搜索引擎之上的搜索引擎。它的主要精力放在提高搜索速度、智能处理搜索结果、个性化搜索和用户检索界面的友好性上。元搜索引擎的全面性和准确度都比较高。

Google的搜索引擎性能优良,因为它使用了先进的硬件和软件。以往的大多数的搜索引擎是使用少量大型服务器。在访问高峰期,搜索的速度就会明显减慢。Google则利用在互联网上相互链接的计算机来快速查找每个搜索的答案,缩短查找时间。Google的搜索软件可同时进行许多运算,它的核心技术就是PageRank™,译为网页排名。
PageRank对搜索结果按重要性排序,这是Google的两个创始人Larry Page和Sergey Brin共同开发的。用户不可能阅读全部的搜索结果(数量极大),而仅查阅显示靠前的项目。因此用户希望检索结果按重要性排序。怎样确定某个页面的重要性呢?传统的搜索引擎往往是检查关键字在网页上出现的频率。PageRank技术则把互联网当作一个整体对待,检查整个网络链接的结构,并确定哪些网页重要性最高。更具体些,就是如果有很多网站上的链接都指向页面A,那么页面A就比较重要。PageRank对链接的数目加权统计。对重要网站的链接,其权重也较大。统计链接数目的问题是一个二维矩阵相乘的问题,从理论上讲,这种二维矩阵的元素数是网页数目的平方。对于1亿个网页,这种矩阵就有1亿亿个元素。这样大的矩阵相乘,计算量是极其可怕的。Larry Page和Sergey Brin两人利用稀疏矩阵计算的技巧,大大简化了计算。他们用迭代的方法解决了这个问题。他们先假定所有网页的排名是相同的,并且根据此初始值,算出各个网页的第一次迭代排名,再根据第一次迭代排名算出第二次的排名。他们从理论上证明了:不论初始值如何选取,这种算法都保证了网页排名的估计值能收敛到排名的真实值。这个算法是完全没有任何人工干预的,厂商无法用金钱购买网页的排名。Google还要进行超文本匹配分析,以确定哪些网页与正在执行的特定搜索相关。在综合考虑整体重要性以及与特定查询的相关性之后,Google就把最相关、最可靠的搜索结果放在首位。
然而某些网站通过“竞价排名”把虚假广告信息放在检索结果的首位,结果误导了消费者,使之蒙受巨大损失。因此对网络搜索的结果,我们应认真分析真伪、提高辨别能力,不要随意轻信网络检索的广告信息(哪怕是知名度很高的网站)。

猜你喜欢

转载自blog.csdn.net/COFACTOR/article/details/109129851