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

专业课 同时被 2 个专栏收录
61 篇文章 1 订阅
9 篇文章 0 订阅

计算机网络

知 识 梳 理

(第一版)

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


链接:https://pan.baidu.com/s/1QGAsUur33TPXdJicMHupGw
提取码:0000


二 应用层

声明
本书涉及的网站:www.3134.com、jasmine.org、www.oust.edu.cn和gakuen-toshi.ac.jp,均为针对举例而杜撰的假想网站。本书发布后,经检验,部分网站存在有害信息。此情况纯属巧合。请大家珍爱生命,远离恶意网站。
2.1 网络应用背后的原理
现代网络应用程序常用的架构是:客户端-服务器(client-server,C-S)结构和对等(peer-to-peer,P2P)结构。
C-S体系结构中,长期在线的主机称为服务器,服务来自其它主机(客户端)的请求。当Web服务器收到客户端的浏览器对对象的请求时,将请求的对象发送到客户端主机作为响应。在C-S结构中,客户端不直接进行通信。此外,服务器具有一个固定的、众所周知的IP地址(见后文)。又因为服务一般长期运行,所以客户端始终可以通过向服务器的IP地址发送数据包,来与服务器联系。具有C-S体系结构的应用有:Web、FTP、Telnet和电子邮件等。
通常,在C-S应用程序中,单服务器无法满足所有请求。如果社交网站只有1台服务器处理请求,那么很快就会不堪重负。因此,常使用数据中心。搜索引擎(例如Google、Bing、百度),互联网商务(Amazon、eBay、阿里巴巴,等),基于Web的电子邮件(例如Gmail和Yahoo Mail),社交网络(如,Facebook、Instagram、Twitter和微信)等,都使用若干个数据中心。数据中心可以具有数十万服务器,必须保证供电和维护。此外,服务提供商必须为其数据中心支付互连和带宽成本。
在P2P架构中,对专用服务器的依赖很小(或没有)。相反,应用程序利用间歇连接,在主机之间直接通信,这些主机称为对等方(peers)。对等方不属于服务提供商,而属于用户自己,它们多位于家庭、大学和办公室。对等方无需通过专用服务器通信,因此称为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章)。
一旦应用程序开发人员选择了传输协议(如果可选),就使用该协议提供的运输层服务来构建应用程序。

为了识别接收进程,需要指定2条信息:主机的地址、目标主机中的接收进程的标识符。
在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)也能保证。除了秘密性,传输协议还可以提供其它安全服务,包括数据完整性和端点身份验证。

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

应用程序 数据丢失 吞吐量 延迟敏感
文件传输 / 下载 不允许 一般无要求 无
电子邮件 不允许 一般无要求 无
Web文档 不允许 一般无要求 无
Internet电话 / 视频会议 容许一定的丢失 例如:音频32 ~ 1536 kbps
视频200 ~ 10000 kbps 例如:几百ms
流音频 / 流视频 容许一定的丢失 例如:几s
交互游戏 容许一定的丢失 例如:10 kbps左右 例如:几百ms
智能手机短信 不允许 一般无要求 可能有

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

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

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

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

应用程序 应用层协议 运输层协议
电子邮件 SMTP TCP
远程终端访问 Telnet TCP
Web HTTP / HTTPS TCP
文件传输 FTP / TFTP / SFTP FTP / SFTP:TCP
TFTP:UDP
流媒体 HTTP / HTTPS, DASH或私有的协议 UDP / TCP
Internet电话 SIP, RTP或私有的协议 UDP / TCP
名称转换 DNS UDP
路由选择 RIP, OSPF RIP:UDP
OSPF:不使用运输层协议,直接使用IP
自动配置IP地址 IPv4:DHCP
IPv6:有状态配置时使用DHCPv6 UDP
远程文件服务器 NFS(网络文件系统) UDP
网络管理 SNMP UDP
多播 IPv4:IGMP
IPv6:MLD UDP

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

某些应用层协议在RFC中指定。遵循HTTP RFC规则的浏览器能够从同样遵循HTTP RFC规则的任何Web服务器中检索网页。许多应用层协议是专有的,在公共领域不可用。例如,Skype使用专有的应用层协议。
区分网络应用程序和应用层协议非常重要。应用层协议只是网络应用程序的一部分,定义的是应用进程间通信和交互的规则。Web是一个C-S结构应用程序,允许用户从Web服务器获取文档。Web应用由许多组件组成,包括文档格式标准(HTML)、浏览器(例如Chrome、Firefox和Microsoft Edge)、Web服务器(例如Apache和Microsoft IIS)及应用层协议。Web的应用层协议HTTP定义了浏览器和Web服务器之间交换的消息的格式和顺序。因此,HTTP只是Web应用程序的一部分。电子邮件应用程序具有许多组件,包括容纳用户邮箱的邮件服务器;允许用户阅读和创建消息的邮件客户端(例: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伦敦奥运会(The London 2012 Summer Olympics)开幕式上,Tim Berners-Lee爵士亮相,并在一台NeXT计算机上打出了“This is for Everyone”字样。言外之意,互联网献给所有人。2017年,他因“发明万维网、第一个浏览器和使万维网得以扩展的基本协议和算法”,获得2016年度的图灵奖(Turing Award)。

万维网是分布式超媒体(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文本和5个PNG图像,则该网页具有6个对象。基本HTML文件使用对象的URL引用页面中的其它对象。关于HTML的介绍,参见本节后文。
URL包含两部分:存储该对象的服务器的主机名(hostname),以及该对象的路径名(pathname)。例如:

https://cse.oust.edu.cn/courses/nlp/intro.pdf
的主机名是cse.oust.edu.cn,路径名是/courses/nlp/intro.pdf。Web浏览器实现了HTTP的客户端,所以浏览器和客户端在这里是同义词。Web服务器实现HTTP的服务器端,存储了Web对象,每个对象都可以通过URL寻址。
HTTPS是使用安全套接层(SSL)的HTTP,将在8.6节学习SSL。
URL使用ASCII作为字符编码。其一般格式是:
<协议>://<主机>:<端口>/<路径>
常见的协议有http、ftp和https。现在的浏览器为了方便用户,在输入URL时,可以把最前面的http://和主机名最前面的“www”省略,浏览器替用户把省略的字符添上。
HTTP的URL的一般形式是:
http://<主机>:<端口>/<路径>
HTTP的默认端口是80,通常可以省略。若再省略<路径>,则URL指向互联网上的某个主页(homepage)。
主页通常是:
(1) 一个WWW服务器的最高级别的页面。
(2) 组织或部门的定制页面或目录。这样的页面可以链接到互联网上的与本组织或部门有关的其它站点。
(3) 由某人自己设计的描述他本人情况的WWW页面。
在URL的尾部,还可以添加可选的请求串(query string)。请求串部分是由ASCII字符“?”开头的。它的语法并没有明确定义,但传统一般是:“?”后跟随若干个key-value对,用分隔符分开。例如:
https://3134.com/user/AndyBayerRoswell/worklist?filetype=audio&access=public

https://3134.com/user/AndyBayerRoswell/worklist?filetype=audio;access=public
在URL的尾部,还可以添加可选的分段(fragment),其开头为ASCII字符“#”。分段包含一个分段标识符(fragment identifier),提供到其它资源的重定向。比如,文章的段标题可以做成链接,链接就由URL的分段部分指示。当首选资源是HTML文档时,分段一般是特定元素的id标识符。点击带“#”的这类链接,浏览器将该元素滚动到指定位置显示。

HTTP定义Web客户端如何从Web服务器请求页面,以及服务器如何将网页传输到客户端。当用户请求Web页面时(例如,单击超链接,hyperlink),浏览器会将页面中的该对象的HTTP请求报文发送到服务器。服务器接收请求,并使用包含该对象的HTTP响应报文进行响应。
HTTP使用TCP作为基础传输协议而不是UDP。HTTP协议本身是无连接的。HTTP客户端首先启动与服务器的TCP连接。建立连接后,浏览器和服务器进程通过其套接字接口访问TCP:客户端通过其套接字接口发送HTTP请求报文并接收HTTP响应报文;HTTP服务器从其套接字接口接收请求报文并发送响应报文。客户端将报文发送到其套接字接口后,该报文就不再由客户端而由TCP控制。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),我们来看一看将网页从服务器传输到客户端的步骤。假设该页面包含1个基本HTML文件和10个PNG图像,基本HTML文件的URL是

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

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

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

非持久连接有一些缺点。首先,必须为每个请求的对象建立并维护一个全新的连接。对每一个连接都必须分配TCP缓冲区,并且必须在客户端和服务器中都保留TCP变量。这可能会给Web服务器带来沉重负担。其次,每个对象会带来2个RTT的传播延迟,分别用于建立TCP连接、请求和接收对象。
有了HTTP 1.1持久连接(persistent connection),服务器在发送响应后保持TCP连接,用于发送同一客户端和服务器之间的后续请求和响应。具体而言,整个Web页面(上例包含基本HTML文件和10个图像)可以通过单个持久TCP连接发送。单个持久TCP连接还能将同一服务器上的多个Web页面发送到同一客户端。这些对对象的请求可以紧密发出,而无需一直等待答复(流水线化)。通常,HTTP服务器在一定时间(可更改)未通过该连接通信后,会关闭连接。当服务器接收到高密度的请求时,它将高密度地发送对象。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文本编写的,所以可以直接阅读。其次,该报文由5行组成,每行的末尾是行分隔符CRLF,包括最后一行。HTTP请求报文有数行。第一行和随后的若干行分别称为请求行(request line)和报头行(header lines,首部行)。请求行包含3个字段:方法字段、URL字段和HTTP版本字段。方法字段可以是:GET,POST,HEAD,PUT和DELETE。多数HTTP请求使用GET方法。当浏览器请求一个对象时,使用GET方法,且在URL字段中标识所请求的对象。在此示例中,浏览器正请求/video/index.html,使用HTTP / 2.0。
本例中,报头行Host: www.3134.com指定对象所在的主机。您可能会认为此报头行是不必要的,因为已经有到主机的TCP连接。但Web代理缓存需要主机报头行提供的信息(见下文)。通过添加Connection: close报头行,浏览器告诉服务器:不想建立持久连接,希望服务器在发送请求的对象后关闭连接。User-agent报头行指定用户代理(User Agent,UA)。UA是代表使用者行为的软件代理程序提供的自己的标识符,在这里是向服务器发出请求的浏览器类型:Firefox浏览器Mozilla / 5.0。该报头行允许服务器将同一对象的不同版本发送给不同类型的UA(每个版本可以使用相同的URL),典型的例子就是网站的桌面版和移动版。最后,Accept-language报头指示用户希望接收对象的简体中文版本。如果服务器上存在该对象,则发送之;否则,服务器发送默认版本。Accept-language报头只是HTTP中可用的许多内容协商报头之一。
报头可以有好几行,但也可以不使用。

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

方法(操作) 意义
OPTION 请求一些选项的信息
GET 获得URL对应的内容
HEAD 获得URL对应的内容的头部
POST 向服务器发送附带信息(如,注释或密码)的请求
PUT 向服务器上传数据到URL对应的位置
DELETE 删除指定URL对应的数据
TRACE 进行回环测试的请求报文
CONNECT 用于代理服务器

对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行报头行,然后是实体本体(主体)。实体主体是报文的基础,它包含所请求的对象本身。状态行具有3个字段:协议版本字段,状态代码和相应的状态信息。在此示例中,状态行指示服务器正在使用HTTP / 2.0,并且一切正常(已找到并正在发送请求的对象)。
现在看报头行。Connection: close告诉客户端,将在发送响应后关闭TCP连接。Date报头行指示服务器创建和发送HTTP响应的日期时间。注意,这不是对象的创建或最后修改时间,而是服务器检索对象、将其插入响应报文并发送的时间。Server报头行指示该报文是由Apache Web服务器生成的;它类似于HTTP请求中的User-agent报头行。Last-Modified报头行指示创建或最后修改对象的日期时间。它对于本地客户端和网络高速缓存服务器中的对象缓存至关重要。Content-Length报头行指示要发送的对象的字节数(若不注意这点,可能在后端编程中遇到奇怪的问题)。Content-Type报头行表示实体主体中的对象是HTML文本(对象类型由Content-Type报头而不是文件扩展名正式表示)。

响应报文的一般格式如上图。状态代码和相关的短语表示请求的结果。

状态码 类别 例 含义
1xx 通知 100 Continue 继续。
101 Switching Protocols 正在切换协议。
102 Processing 处理中。
2xx 成功 200 OK 请求成功。
201 Created 对象已创建。
202 Accepted 服务器端已经收到请求消息,但尚未进行处理。
3xx 重定向 301 Moved Permanently 请求的对象已被永久移动;新的URL在响应报文的Location报头行中指定,客户端将检索新的URL。
304 Not Modified 请求的对象在指定日期后未被修改。
4xx 客户端错误 400 Bad Request 服务器无法理解该请求。
403 Forbidden 服务器(已理解请求但)拒绝该请求。
404 Not Found 找不到指定的对象。
5xx 服务器错误 500 Internal Server Error 内部服务器错误。
502 Bad Gateway 在网关访问下一个服务器时出错。
505 HTTP Version Not Supported 服务器不支持所请求的HTTP版本。

如何查看真实的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文件。如果只想查看报头行而不接收对象,则将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报头中的标识号。注意:cookie文件已经具有eBay的条目。随着Susan继续浏览Amazon,每次她请求一个网页时,浏览器都会查询她的cookie文件,提取站点的标识号,并将包含标识号的cookie报头行放在HTTP请求中。具体来说,她对Amazon服务器的每个HTTP请求都包含报头行
Cookie: 31d4d96e407aad42
通过这种方式,Amazon服务器记录Susan在该网站的活动。Amazon未必知道Susan的真名,但知道用户31d4d96e407aad42以什么顺序、在什么时间访问了哪些页面。Amazon使用cookie实现购物车服务——维护Susan所有预定购买的清单,以便她日后可以为它们一同付款。

如果Susan以后返回Amazon网站,则她的浏览器将继续在请求报文中添加报头行:

Cookie: 31d4d96e407aad42
Amazon还根据她访问过的网页推荐产品。如果Susan也在Amazon注册(提供全名、邮件地址、邮政地址和信用卡信息等),那么Amazon可以将该信息写入到数据库,从而将Susan的姓名与ID及过去曾在该网站访问过的内容关联。这就是电商网站提供的“一键购物”:Susan在后续购买商品时,无需重新输入姓名、信用卡号或地址。
Cookie可以用来识别用户。用户首次访问站点时,可以提供用户标识(可能是他或她的名字)。在后续会话期间,浏览器将cookie报头传递给服务器,从而为服务器标识用户。因此,可使用cookie在无状态HTTP之上创建用户会话层。比如,当用户登录Web邮件应用(例如Hotmail)时,浏览器将cookie信息发送到服务器,从而允许服务器在用户与应用程序的整个会话过程中识别用户。
Cookie之所以引起争议,是因为它们也可能侵犯隐私。结合Cookie和用户提供的帐户信息,网站可以了解很多有关用户的信息,并可能将该信息出售给第三方。Cookie Central包含有关Cookie争议的广泛信息。
有人认为Cookie会把计算机病毒带到用户的计算机中。其实这是对Cookie的误解。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缓存。
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。它告诉缓存:可以将对象的缓存副本转发给请求的浏览器。

HTTP/2在2015年标准化,是HTTP/1.1之后的第一个新版本,后者在1997年标准化。自从HTTP/2标准化后,到2020年,在前1000万网站中,已经有超过40%使用HTTP/2。许多浏览器,包括Google Chrome、Internet Explorer、Safari、Opera和Firefox,都已支持HTTP/2。
HTTP/2的首要目标是:通过在单个TCP连接上启用请求和响应的复用(multiplexing),减少感知的延迟,提供请求优先级和服务器推送机制,并提供HTTP报头字段的高效压缩。HTTP/2未对HTTP方法、状态码、URL和头部字段做出改动。相反,HTTP/2改变了数据如何在客户端与服务器之间格式化与传送。
HTTP/1.1使用持久连接,允许一个Web页面通过单个TCP连接发送给客户端。每个连接一个Web页面,使服务器端的Socket数量减少,且每个运输的网页能获得公平的网络带宽份额。但浏览器的开发者们很快发现,通过单个TCP连接在单一的Web网页中发送全部对象,会带来线路头端阻塞(Head of Line blocking)问题。设想一个Web页面包含一个HTML基本页面,接近网页顶部的一个大的视频剪辑和视频下方的许多小对象。并假设存在瓶颈链路。使用单个TCP连接时,视频剪辑需要很长的时间穿过瓶颈链路,小对象们一直被延迟加载,因为它们位于视频剪辑之后。即:位于线路头端的视频剪辑阻塞了之后的全部小对象。HTTP/1.1浏览器一般通过打开多个并行的TCP连接解决这个问题,令同一网页中的对象并行发送到浏览器。通过这种方式,小对象到达并被渲染会快得多,于是减少了用户感知的延迟。
TCP拥塞控制(第3章)也会令浏览器计划之外地使用并行TCP连接。粗略地讲,TCP拥塞控制的目的在于:让每个TCP连接公平分享瓶颈链路的可用带宽。使用多个TCP连接传输单个网页,浏览器能够“作弊”,获得更多链路带宽。许多HTTP/1.1浏览器最多打开6个并行TCP连接,不仅为了避免线路头端阻塞,也为了获得更多带宽。
HTTP/2的一个主要目标是:避免(至少减少)传输单个网页的并行TCP连接。这不但减少了服务器需要打开并维护的Socket数量,还能允许TCP拥塞控制预期实施。然而,HTTP/2需要小心设计的机制避免线路头端阻塞。

HTTP/2的线路头端阻塞的解决方案是:将每一份报文分开成小的帧(frame),并在同一TCP连接中交错请求和响应报文。设一个Web网页具有一个大的视频剪辑和n(例如,n=8)个小对象。服务器会从浏览器收到(n+1)个请求。假设所有帧都是等长的,视频片段包含n_V(例如,1000)帧,其它小对象每个只占n_s(例如,2)帧,n_s≪n_v。如果不使用交错发送,只有在全部传输完n_V帧后,才能传输剩余的n_s帧。
将HTTP报文划分成独立的帧,并交错传输,最后在另一端重组成正确的数据,是HTTP/2最重要的增强。HTTP/2的帧划分子层(framing sub-layer)完成帧的划分。当服务器需要发送HTTP响应的时候,响应被帧划分子层处理。响应的报头字段单独成一帧,报文本体被划分成若干帧。这些帧与经由同一个持久TCP连接传送的响应帧一起,由帧划分子层交错传输。帧到达客户端后,先在帧划分子层被重组成原始的响应报文,再被浏览器照常处理。类似地,客户端的HTTP请求也被划分成帧,并交错传输。
帧划分子层还负责二进制编码帧。二进制协议的语法分析效率更高,更易产生短的帧,且错误率更低。

报文优先级机制允许开发者自定义请求的相对优先级,以优化应用程序性能。当客户端并发请求服务器时,它为每份报文的响应指派1到256的优先级。更高的数字代表更高的优先级。使用这些权重,服务器能够首先发送高优先级的响应帧。此外,客户端还能通过报文ID,指明报文间的依赖关系。
HTTP/2的另一个特性是:令服务器可以为同一个客户端请求发送多个响应,服务器能向客户端推送(push)附加的对象,而无需等待客户端再发送请求。这可能是因为HTML基本网页指定了完整渲染网页需要的对象。服务器能分析HTML页面,识别需要的对象,并在收到对这些对象的显式请求之前发送它们。服务器推送消除了等待请求的额外延迟。

第3章将会提到QUIC,是一种在应用层实现的基于裸的UDP的新型“运输”协议。QUIC具备HTTP期望的几个特性,例如报文复用(交错),流(stream)级别的流量控制,以及低延迟连接建立(low-latency connection establishment)。HTTP/3是在QUIC上运作的新型协议。在2020年,HTTP/3处于Internet草案(draft)状态,尚未完全标准化。许多HTTP/2特性(比如报文交错)已经被QUIC包括在内,允许更简易的、流线型的HTTP/3设计。

要使任何计算机都能显示WWW服务器上的页面,就必须解决页面的标准化问题。超文本标记语言(HyperText Markup Language,HTML)是一种制作WWW页面的标准语言,消除了计算机之间信息交流的障碍。注意,HTML并不是应用层协议,它只是WWW浏览器使用的一种语言。HTML易于掌握、实施简单,很快就成为WWW的重要基础。官方的HTML标准由WWW联盟(WWW Consortium,W3C)负责制定。1993年问世后,HTML就不断在更新。现在最新的版本是HTML 5(2014年9月发布),新的版本增加了在网页中嵌入音频、视频,在移动设备上支持多媒体,以及交互式文档等功能。现在一些主流的浏览器都支持HTML 5。
HTML定义了许多用于排版的命令,即标签(tag)。例如,<I>表示后面开始用斜体排版,而</I>则表示斜体字排版到此结束。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的优点是:它将用户界面与结构化数据分隔开来。这种数据与显示的分离,使得集成来自不同源的数据成为可能。客户信息、订单、研究结果、账单付款、病历、目录数据及其它信息,都可以转换为XML。XML不是要替换HTML,而是对HTML的补充。XML标记由文档的作者定义,并且是无限制的。HTML标记则是预定义的;HTML作者只能使用当前HTML标准所支持的标记。
另一种语言XHTML(Extensible HTML)即可扩展超文本标记语言,它与HTML 4.01几乎是相同的。但XHTML是更严格的HTML版本,也是一个W3C标准(2000年1月制定),是作为一种XML应用被重新定义的HTML,并将逐渐取代HTML。所有新的浏览器都支持XHTML。

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

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

通用网关接口(Common Gateway Interface,CGI)是一种标准,它定义了动态文档应如何创建,输入数据应如何提供给应用程序,以及输出结果应如何使用。取这个名字的原因是:WWW服务器与CGI的通信遵循CGI标准。“通用”是因为标准定义的规则对其它任何语言都是通用的。“网关”二字的出现是因为,CGI程序还可能访问其它服务器资源,如数据库或图形软件包,因而CGI程序的作用有点像一个网关。也有人将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 电子邮件
电子邮件(E-mail)是互联网上使用最多的和最受用户欢迎的一种应用。电子邮件把邮件发送到收件人使用的邮件服务器,并放在其中的收件人邮箱(mail box)中,收件人可在自己方便时,上网到自己使用的邮件服务器进行读取。这相当于互联网为用户设立了存放邮件的信箱,因此e-mail有时也称为“电子信箱”。电子邮件不仅使用方便,而且还具有传递迅速和费用低廉的优点。据有的公司报道,使用电子邮件后,劳动生产率可以提高30%以上。

简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)是Internet电子邮件的核心。SMTP将邮件从发件人的邮件服务器传输到收件人的邮件服务器。SMTP比HTTP古老得多。

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

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

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

来看SMTP客户端(C)和SMTP服务器(S)之间交换邮件的示例。客户端与服务器分别是student.oust.edu.cn和oest.no.jasmine.org。以C和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: alice@student.oust.edu.cn
S: 250 alice@student.oust.edu.cn … Sender ok
C: RCPT TO: bob@oest.no.jasmine.org
S: 250 bob@oest.no.jasmine.org … 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及其它可选报头行。这些报头行与之前的SMTP命令不同(即使它们包含一些相同的词,如from、to)。那部分中的命令是SMTP握手协议的一部分;这里的报头行是邮件本身的内容的一部分。典型的邮件报头行如下所示:

From: alice@student.oust.edu.cn
To: bob@sth.se.jasmine.org
Subject: I am planning a departure to your university following the schedule of School of Literature and School of Film and Television of OUST Shanghai. 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或一些公司维护。
在Foxmail中,有一种“特快专递”服务。这种服务就从发件人的UA直接利用SMTP把邮件发送到接收方邮件服务器。这就加快了邮件的交付(省去在发送方邮件服务器中的排队等待时间)。但这种“特快专递”和邮政直接把邮件送到用户家中不同,它并没有把邮件直接发送到收件人的计算机中。有些邮件服务器为了防止垃圾邮件和计算机病毒,拒绝接收从一般用户直接发来的邮件。

思考一下电子邮件从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 <username>和pass <password>。为说明这两个命令,你可以尝试Telnet到POP3服务器,使用端口110,并发出以下命令。假设<MailServer>是邮件服务器名。您将看到类似如下内容:

telnet 110
+OK POP3 server ready
user bob
+OK
pass hungry
+OK user successfully logged on

使用POP3的用户代理可被配置为“下载并删除”或“下载并保留”方式。POP3用户代理发出的命令序列取决于选用哪种工作方式。使用下载并删除方式,用户代理发出list、retr和dele命令。
用户代理首先请求邮件服务器列出所有存储的报文的长度,接着取回并删除每封邮件。授权阶段以后,用户代理仅使用4个命令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的访问界面。Google、Yahoo以及几乎所有重要的大学或者公司,也都提供了基于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转换为若干个空格。
(5)发送电子邮件不需要经过鉴别(authentication)。这就是说,在 FROM命令后面的地址可以任意填写。这就大大方便了垃圾邮件的作者,给收信人添加了麻烦(有人估计,在全世界所有的电子邮件中,垃圾邮件至少占到50%以上,甚至高达90%)。

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

多用途互联网邮件扩展(Multipurpose Internet Mail Extensions,MIME)可以解决大部分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码的数据的编码方法是:先将每个字节的二进制代码用2个十六进制数字表示,然后在前面再加上一个等号“=”。例如,汉字的“系统”的二进制编码是:11001111101101011100110110110011(共32位,4个字节都不是ASCII码),用十六进制表示为:CFB5CDB3;用quoted-printable编码表示为:=CF=B5=CD=B3。这12个字符都是可打印的ASCII字符,占用96位,和原来的32位相比,开销达300%。而等号“=”的二进制代码为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),中间用“/”分开。例如:text/plain、image/png。截至2021年9月,内容类型一共有9大类,如下表。
除了类型和子类型,MIME允许发件人和收件人自己定义专用的内容类型。但为避免名称冲突,标准要求:专用内容类型的名称要以字符串X-开始(例如:audio/x-flac)。目前,子类型的数目还在不断地增加。

类型 子类型举例 说明
application javascript、json、pdf、zip 应用程序产生的数据
audio aac、ac3、AMR、ogg、opus 音频
font ttf 字体
image gif、jpeg、png、tiff 图像
message http、rfc822 报文
model vrml 3D模型
multipart alternative、digest、mixed、parallel 多种类型的组合
text css、csv、html、plain、rtf、xml 文本
video 3gpp、AV1、H264、H265、JPEG2000、mp4、quicktime、raw、VP8、VP9 视频
MIME的内容类型中的multipart是很有用的,因为它使邮件增加了相当大的灵活性。MIME标准为multipart定义了四种可能的子类型,每种子类型都提供重要功能。
(1)mixed子类型允许一份报文含有多份相互独立的子报文,每份子报文可以有自己的类型和编码。mixed子类型报文使用户能够在单个报文中附上文本、图形和声音,或用额外数据发送备忘录,类似商业信笺含有的附件。在mixed后面还用到关键字Boundary=,定义分隔报文各部分的字符串(由邮件系统定义),只要在邮件的内容中不出现这样的字符串即可。当某一行以两个连字符“–”开始,后面紧跟上述的字符串,就表示下面开始另一子报文。
(2)alternative子类型允许单份报文含有同一数据的多种表示。给使用不同硬件和软件系统的收件人发送备忘录时,这种类型很有用。例如,用户可同时用普通的ASCII文本和格式化的形式发送文本,从而允许拥有图形功能的计算机用户在查看图形时选择格式化的形式。
(3)parallel子类型允许单份报文含有可同时显示的各个子部分(例如,图像和声音子部分必须一起播放)。
(4)digest子类型允许单份报文含有一组其它报文(如从讨论中收集电子邮件报文)。
下面是一封MIME邮件,它包含一个简单解释的文本和含有非文本信息的照片。邮件中第一部分的注解说明第二部分含有一张照片。

上面最后一行表示:boundary字符串后还有两个连字符,表示整个multipart的结束。

2.4 DNS
人类能以很多方式标识身份:名字、社会安全号码(SSN)、驾驶证号……。尽管它们都可以标识一个人,但是在特定条件下,总有更适合的方法。IRS(美国那个声名狼藉的税务征收机构)的计算机更喜欢使用定长的SSN而不是出生证书上的姓名;普通人乐于使用更好记的姓名而不是SSN。想想看:“你好,我叫132-67-9875。请找一下我的丈夫178-87-1146”。这种标识方式是不是很折磨人?
Internet上的主机也可以使用多种方式标识。一种标识方法是主机名(hostname),如www.instagram.com,www.google.com,等等,它们便于记忆。然而,主机名只提供了很少或不提供主机在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(也有可能是8080等)或443端口的HTTP / HTTPS服务器进程发起一个TCP连接。
从这个例子可以看到:DNS给使用它的Internet应用带来了额外的时延,有时还相当可观。幸运的是,想获得的IP地址通常就缓存在附近的DNS服务器,这有助于减少DNS的网络流量和平均时延。

除了进行主机名到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@jasmine.org这样简单。不过,邮件服务器的主机名可能更为复杂,例如:规范主机名可能像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协议是应用层协议,因为它:
(1)运行在通信的端系统之间,使用C-S范式。
(2)依赖下层的端到端运输协议在端系统间传输DNS报文。
然而,在另一种意义上,DNS的角色与Web、文件传输、Email等相当不同。DNS并不是与用户直接交互的应用程序。相反,DNS提供一项Internet核心功能:为用户应用程序和Internet上的其它软件翻译主机名为IP地址。DNS同样位于网络边缘,再次体现了Internet将大部分复杂度置于网络边缘的设计哲学。

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

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

从语法上讲,每一个域名都由标号(label)序列组成,而各标号之间用点隔开(请注意,是小数点“.”不是中文的句号“。”)。例如:域名

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

顶级域名共分为三大类:
(1)国家顶级域名nTLD:
采用ISO 3166的规定。如:cn表示中国,us表示美国,uk表示英国,等等。nTLD又常记为ccTLD(cc表示country-code)。ccTLD也包括地区的域名,如:香港特别行政区(hk)和台湾省(tw)都是ccTLD里的顶级域名。此外,国家顶级域名可以使用一个国家自己的文字。例如,中国可以有“.cn”、“中国”和“中國”3种域名。
(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地址中的“子网”也没有关系。

与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服务器不可能距离所有客户都较近。如果将它放在纽约市(New York City),那么来自澳洲的查询必须绕到地球的另一边,中间也许还要经过低速和拥塞的链路,带来严重时延。
·维护(maintenance)。单台DNS服务器不得不为所有的Internet主机保留记录。这不仅将使这个中央数据库极度庞大,而且它还不得不为解析每台新添加的主机而频繁更新。
总的来说,在单一DNS服务器上运行集中式数据库完全没有可扩展性。因此,DNS采用了分布式的设计方案。事实上,DNS是一个在Internet上实现分布式数据库的精彩范例。

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

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

根服务器采用了任播(4.3节)技术,因此,DNS客户向某台根服务器的IP地址发出查询报文时,互联网上的路由器就能找到离这个客户最近的一台根服务器。这不仅加快了DNS的查询过程,也更合理地利用了互联网的资源。
目前,根域名服务器的分布仍然很不均衡。如,亚洲的根服务器较少,这使亚洲网民的上网速率明显低于北美。
·顶级域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服务器实际管辖的范围。区可能等于或小于域,但一定不能大于域。
·还有另一类重要的DNS服务器:本地DNS服务器(local DNS server),也称默认域名服务器。严格说来,本地DNS服务器并不属于DNS服务器的层次结构,但它对DNS是至关重要的。每个ISP(如:一个居民区或机构的ISP)都具有本地DNS服务器。当主机与某个ISP连接时,该ISP提供若干台其本地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服务器。
在本例的基础上,假设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服务器在一段时间后(通常是2天)将丢弃缓存的信息。
有了缓存,本地DNS服务器可以立即返回目标主机的IP地址,而不必查询其它DNS服务器。本地DNS服务器也能够缓存TLD服务器的IP地址,因而允许本地DNS绕过查询链中的根DNS服务器。事实上,除了少数DNS查询,一般情况下无需再去询问根服务器,这就是缓存的功劳。
不但在本地域名服务器中需要高速缓存,在主机中也很需要。许多主机在启动时,从本地域名服务器下载域名和地址的全部数据库,维护存放自己最近使用的域名的高速缓存,并且只在从缓存中找不到域名时才使用域名服务器。维护本地域名服务器数据库的主机应定期更新映射信息,且必须及时从缓存中删掉无效的项。由于域名改动并不频繁,大多数网点不需花费太多精力就能维护数据库的一致性。

共同实现DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record,RR)。RR提供了主机名到IP地址的映射。每份DNS回答报文包含若干条资源记录。资源记录是四元组

<Name, Value, Type, TTL>
TTL是生存时间,它决定了资源记录应当从缓存中删除的时间。在下面的段落中,我们省略TTL和 / 或Type字段。Name和Value的值取决于Type:
Value Type 说明 举例
1 A 主机名→主机IPv4地址 <relay-05.nz.3134.com, 202.27.76.2>
2 NS 主机名→权威DNS主机名 <3134.com, dns.3134.com>
5 CNAME 主机名→规范主机名 <3134.com, relay-1a.ca.3134.com>
6 SOA 验证的开始;包含关于域的信息
11 WKS 众所周知的服务
12 PTR IP地址→主机名(逆向查询或指针查询) <2620:0000:10cc:1007:a800:01ff:fe00:a2e1, cse.oust.edu.cn>
13 HINFO 主机信息的描述
15 MX 主机名→邮件服务器的规范主机名 <oust.edu.cn, mail.oust.edu.cn>
28 AAAA 主机名→主机IPv6地址 <shoko.gakuen-toshi.ac.jp, 2001:02E8:0642:0000:0002:0001:0000:0011>
252 XFER 区域转换请求
255 ANY 所有记录请求
如果一台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地址。
NS记录用于沿着查询链来路由DNS查询。DNS服务器无法直接返回主机名对应的IP地址时,如有NS记录,可以返回给DNS客户,DNS客户再去查询NS记录指定的其它权威DNS服务器。
MX记录允许邮件服务器主机名具有简单的别名。值得注意的是,通过使用MX记录,一个公司的邮件服务器和其它服务器(如Web服务器)可以使用相同的别名。为了获得邮件服务器的规范主机名,DNS客户应当请求一条MX记录;要获得其它服务器的规范主机名,DNS客户应当请求CNAME记录。
使用CNAME记录可以很方便地让网站变更IP地址。出于方便记忆等原因,一个网站通常会具有若干个别名。当更换IP地址时,若不使用CNAME,则所有的A和AAAA记录都要修改为新的IP地址。若使用CNAME,则只需要变动CNAME记录的地址。可见,CNAME简化了DNS的管理工作。CNAME还有利于实现CDN(见2.6节)加速。CNAME带来的主要坏处基本上只有一个:第一次解析域名的时候,需要多解析一次,先获得规范名称,再继续常规的解析流程。

DNS只有查询和响应2种报文,并且格式相同。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),3位,必为零。
·应答码字段(reply code)4位,表示是否出错。0表示正常,1表示请求报文格式错误,2表示域名服务器故障,3只对权威服务器有意义:表示解析的域名不存在,4表示不支持查询该类型,5表示拒绝查询。6 ~ 15保留。

QR opcode AA TC RD RA Z Rcode
在该首部中,还有4个有关数量的字段,这些字段的无符号16位整数指出了在首部后的4类数据区域出现的数量。对于请求报文,只有第1个数量字段(问题)不为0。
·问题区域(question section)包含正在进行的查询信息。该区域包括:
①名称字段。即正在被查询的主机名。
②类型(type)字段。指出有关该名字的正被询问的问题类型。
例如:主机地址是与一个名称相关联(类型A),还是与名称的邮件服务器相关联(类型MX)。
③类别(class)字段。IN——Internet;CS——CSNET类(已废弃);CH——CHAOS类;HS——Hesiod。
·在来自DNS服务器的回答中,回答区域(answer section)包含了对最初请求的名称的资源记录。前面讲过,每条资源记录都有Type、Value和TTL字段。该区域可以包含多条资源记录,因为一个主机名能对应多个IP地址。
·权威区域包含了其它权威服务器的记录。
·附加区域包含了其它有用的记录。例如,对于MX请求的回答报文的回答区域包含1条资源记录,提供邮件服务器的规范主机名;该附加区域包含1条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域名的注册。而现在,有许多注册登记机构争抢客户,CANN向各种注册登记机构授权。在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服务器中的缓存部分缓解。一次针对TLD服务器提供商Dyn的攻击发生于2016年10月21日。这次DDoS攻击通过一个包含被Mirai恶意软件感染的至少10万台IoT设备(打印机、IP相机、住宅门禁、婴儿监视器、路由器等)的僵尸网络发起大量的DNS查询请求来完成。在这一整天,Amazon、Twitter、Netflix、GitHub、Spotify、Reddit、Imgur、Soundcloud、PayPal、Airbnb、BBC、CNN、Fox News、The Guardian、NYTimes、Pinterest、PlayStation Network、Quora、WSJ、Xbox Live等大量知名网站都受到干扰。
Mirai是一款恶意软件,它可以使运行Linux的计算系统成为被远程操控的“僵尸”,以达到通过僵尸网络进行大规模网络攻击的目的。Mirai的主要感染对象是可访问网络的消费级电子设备,例如网络监控摄像机和家庭路由器等。受Mirai感染的设备会持续地在互联网上扫描物联网设备的IP地址。Mirai包含一张IP白名单表,其中包括专用网络的私有IP地址以及分配给美国邮政署和美国国防部的IP地址,使用这些地址的设备将不受Mirai感染。
东部夏季时间(EDT)2016年10月21这天,Mirai一共引发了三波大规模的DDoS攻击,峰值流量超过1 Tbps。不计其数的北美站点瘫痪,其中,美国东部受灾最为严重,甚至还波及到了欧洲国家。这几轮攻击直接惊动了美国国土安全部(US DHS)。仅Dyn一家受到攻击的公司的直接损失就超过1.1亿美元,事件的整体损失至少达到数十亿美元。
很快,联邦调查局(FBI)成立了跨国联合行动小组,开始追缉Mirai的作者Anna-senpai。多家大型安全企业和独立个人也进行了调查。作者的反侦察能力很强,控制僵尸网络的信号来源变化多端,难以被锁定。但百密一疏,作者在网上留下的种种信息还是暴露了破绽。例如,独立调查记者Brian Krebs发现了一个叫做Paras Jha的一家DDoS防御服务提供商的总裁。他的LinkedIn资料显示,他的计算机技能与Anna-senpai的技能高度相似。又例如,Mirai和Anna-senpai这两个名字都是来源于日本动漫(分别是《未来日记》和《没有黄段子的无聊世界》)。有一个叫做Dradiscool的用户,总是在网上发布一些当时(指发帖时间前后)的主要DDoS攻击的内容,包括对Rutgers University的一系列DDoS攻击,此外还有其它更多关于Rutgers的内容。而Paras Jha正是毕业于Rutgers。而MyAnimeList上也能找到同名用户Dradiscool的资料。他声称自己看过《B型H系》,而一个Minecraft论坛上也有一个同名的用户Dradiscool,其头像就包含《B型H系》中的角色。此外,专门保护Minecraft服务器的ProxyPipe公司的业务伙伴也声称,Mirai中的一些代码十分类似于Dreadiscool发布到他的GitHub帐户的代码。
在全世界安全社区的共同努力下,FBI最终抓捕了Paras Jha,Josiah White和Dalton Norman三人。Paras Jha果然就是神秘的Anna-senpai,负责Mirai的源代码。Josiah White写了一个扫描器,用于快速发出成千上万的SYN包,令病毒有机会快速感染大量设备。Dalton Norman则找到了4个和摄像头、路由器相关的0-day高危漏洞。
由于Paras Jha攻击了自己的母校Rutgers University,新泽西(New Jersey)地方法院判处他在家监禁6个月,并需要赔偿860万美元。Paras Jha和Dalton Norman还遭阿拉斯加(Alaska)地方法院起诉,Paras Jha被判处三年监管和2500小时的社区服务。2018年9月,阿拉斯加地方法院判处三人5年缓刑、2500小时社区服务和12.7万美元的赔偿,并被要求上缴犯罪期间获得的加密货币。社区服务要求三名被告必须与FBI合作阻止网络攻击。检察官称,“三名被告都表现出了极大的奉献精神”。三人被要求同FBI合作,包括帮助防止圣诞节期间的DDoS攻击,并减轻新的DDoS攻击方法Memcache的影响。他们还帮助FBI开发了一个程序,允许执法部门检查不同格式的加密货币私钥。这些服务也为他们换来了比之前轻得多的处罚。
在Dyn攻击事件开始前的一个月,2016年9月,Anna-senpai将Mirai的源代码公布在了网上。在Mirai的攻击源码被发布到网络之后,各大安全厂商已迅速将其精准绞杀,但是Mirai的代码很快就被各路黑客改写,成为变种,继续在网络中作威作福。例如,2017年,变种之一Rowdy爆发了。它支持多种CPU平台,x86、ARM、MIPS这三大主流CPU架构无一幸免,由其构建的僵尸网络能发动多种DDoS攻击。不过,这次的攻击载体由摄像头等设备变为了电视机顶盒,而且攻击目标在中国,超过2亿台设备都有被成功攻击的风险。虽然由于及时发现,Rowdy被有效遏制了,但类似的IoT僵尸网络一定会不断出现。不少人只是将已有的恶意软件代码做了少量修改,甚至几乎不需要自己具备多少代码能力,而只通过租用其他个人或组织提供的僵尸网络,都有概率令Internet上的主流网站集体掉线。IoT设备,包括摄像头、路由器、智能电视、机顶盒、智能家居和可穿戴设备,只要接入Internet,搭载了相关的操作系统,就有可能成为攻击者的潜在目标。攻击者利用存在漏洞的物联网设备,尤其是未修改缺省弱口令的设备,组成庞大的僵尸网络,为其随时发动大规模DDoS攻击做准备,威胁Internet的安全。此外,用户不易发觉自己的物联网设备已经被控制,用于组建僵尸网络。大多数IoT设备是没有用户界面的,即便有提供界面,用户可能也不常去访问。通过界面去处理这些安全问题,往往也很不方便,乃至干脆不可行。但很可惜,许多厂商依旧没有吸取教训。比如,依然有不少设备厂商没有对固件进行足够的保护,或不及时修复固件存在的安全漏洞,内置密码强度仍旧很弱,甚至有的设备还会以明文形式存储密码——只要是稍微有点儿业务能力的安全人员,都不应该允许这么做。Dyn攻击事件的性质,其实很接近DNS单点故障。具体而言,DNS提供商过少,DNS服务过度集中,甚至能让大公司也面临服务中断的风险。目前还存在相当多的网站使用单一提供商托管的DNS服务器。尽管DNS集中化的危险如此明显,却少有公司愿意拨冗实现备份DNS。事实上,1997年的RFC 2182就已经写道:“每个域采用多台域名服务器的主要原因,是要让该域的信息能够在互联网上广泛而可靠地访问,即便其中一台域名服务器宕机了。”
DNS还会以其它方式被攻击。在中间人攻击(man-in-the-middle attack)中,攻击者截获来自主机的请求并返回伪造的回答。在DNS污染(DNS poisoning)攻击中,攻击者向一台DNS服务器发送伪造的回应,诱使其在缓存中存储伪造的记录。这些攻击中的任意一种,都能将Web用户重定向到攻击者的Web站点。然而,这些攻击难以实现,因为它们要求截获分组或设法降低服务器的响应速率。DNS安全扩展(DNSSEC),一个安全版本的DNS,能处理许多这些可能的攻击,已在Internet上获得越来越高的流行程度。总之,DNS已经具备一定的健壮性(robustness)。

2.5 P2P应用举例:文件传输

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

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

设有n台主机从服务器下载一些大文件,总长度为L。主机i与互联网连接的链路的理论上传和下载速率分别为v_(u,i)和v_(d,i)。
如果采用传统的C/S结构,则:
·服务器为每台主机分发全部所需文件的时间不少于nL/v_(u,s),其中,v_(u,s)为服务器上传数据到网络的最高速率。
·如果下载最慢的主机的下载速率为v_(d,min),则该主机下载所需文件花费的时间不少于L/v_(d,min)。

因此,所有主机都下载完总大小为L的文件需要的最少时间是
T_CS=max⁡(nL/v_(u,s) , L/v_(d,min) )
如果采用P2P方式,则:
·服务器将文件发送给第一台主机的花费的时间不少于L/v_(u,s)。
·下载最慢的主机将所需文件下载完毕花费的时间不少于L/v_(d,min)。
·文件全部分发给n台主机花费的时间不少于nL/v_(u,TOTAL)。其中,v_(u,TOTAL)是参与上传的全部主机的速率之和。显然,v_(u,TOTAL)是一个理想的最大值。文件总是要在开始时先由服务器单独分发给一些主机,得到文件(或其一部分)后的主机再分发给其它需要这些文件的主机,在这样的过程中,逐渐令上传总速率接近理论最大值v_(u,TOTAL)。
因此,所有主机都下载完总大小为L的文件需要的最少时间是
T_P2P=max⁡(L/v_(u,s) , L/v_(d,min) , nL/v_(u,TOTAL) )

最早使用P2P工作方式的是Napster,它由1999年美国东北大学的新生Shawn Fanning所写。利用这个软件,可通过互联网免费下载各种MP3音乐。Napster的出现,使MP3成为网络音乐事实上的标准。
Napster能够搜索音乐文件。所有音乐文件的索引信息都集中存放在Napster目录服务器中。目录服务器起着索引的作用。使用者只要查找目录服务器,就能知道应从何处下载需要的MP3文件。在2000年,Napster成为互联网上最流行的P2P应用,并占据互联网上的通信量中相当大的比例。
这里的关键是:运行Napster的所有用户,都必须及时向Napster的目录服务器报告自己已经存有哪些音乐文件。Napster目录服务器利用这些信息建立一个动态数据库,集中存储了所有用户的音乐文件信息(文件名和相应的IP地址)。当用户想下载MP3时,就查询目录服务器(这个过程仍是传统的C-S方式)。目录服务器检索出结果后,向用户返回存放这一文件的计算机的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加入该洪流时,追踪器随机选择对等方的一部分(比如50个),并将它们的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接收到任何块。
这种激励机制常被称为“一报还一报”(tit-for-tat),不过它也是能被绕过的。但无论如何,BitTorrent的生态系统取得了广泛成功。如今,亿万对等方在无数的洪流中积极地共享文件。如果BitTorrent不采用此种机制(或其变种),它将很可能不复存在,因为大多数人会选择只吃饭不干活,下完东西就溜,而不通过上传为别人做种。
BitTorrent还有一些机制没有在这里讨论,包括分片(pieces)、流水线、随机优先选择、残局模式(endgame mode)和反怠慢(anti-snubbing)。

分布式散列表(distributed hash table,DHT)也是P2P的应用,它是一种简单的数据库,分布在一个P2P系统的多个对等方上,由大量对等方共同维护。DHT得到了广泛实现(如在BitTorrent中),并成为大量研究的主题。
在BT中,DHT主要用于迅速找到所需的文件。本质上说,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
如果哈希函数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+2^0,x+2^1,…,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
串流(Streaming),是指將影音资料經過網際網路分段傳送,在網路上即時傳輸影音的一種技術。
讨论视频串流之前,先简单回顾一下视频。视频是一系列的图像,通常以恒定帧率(CFR,如23.976 fps或25 fps或30 fps)或可变帧率(VFR)来展现。一帧未压缩的图像是二维的像素阵列,每个像素包含表示亮度和颜色的位。视频能够被(无损或有损)压缩,我们用比特率来衡量视频质量。现有的压缩算法能够将一个视频压缩成所希望的任何比特率。比特率越高,图像质量越好。通常,视频的比特率随时间而变化。
压缩的网络视频的比特率可以是很低的100到200 kbps,也可以超过3到10 Mbps。为了连续不断地播放多媒体内容,网络必须为流式应用提供平均吞吐量,不能低于视频的比特率。通常,网站准备了相同视频的多个版本,它们画质不同。用户根据可用带宽决定观看哪个版本。

在HTTP串流中,视频只是存储在HTTP服务器中的一个普通的文件,每个文件有特定的URL。观看视频时,客户与服务器创建一个连接,并发送对该URL的HTTP GET请求。服务器借助底层网络协议和尽可能快的速率,在HTTP响应报文中发送该视频。在客户端,字节被保存在应用的缓冲区。一旦缓冲的字节数超过预设的阈值,应用程序就开始播放。流式视频应用程序周期性地从缓存中抓取帧,解压并输出,同时缓存视频后续部分的帧。
尽管HTTP串流在实践中已经得到广泛部署(例如YouTube),但它具有严重缺陷:所有客户接收到的都是相同的视频,尽管不同情况下可用的带宽大小不同。于是,经HTTP的动态适应性串流(Dynamic Adaptive Streaming over HTTP,DASH)被发明出来。在DASH中,视频编码为比特率不同的版本。客户端动态请求不同版本的视频数据块。可用带宽较大时,选择高码率的块;否则,选择低码率的块。客户使用HTTP GET请求报文选择不同的块。
DASH对移动用户特别重要。因为当移动用户随着地理位置的改变而自动连接到附近的基站时,网络带宽会波动。使用DASH时,每个视频版本存储在HTTP服务器中,用不同的URL标识。HTTP服务器也有一个清单文件(manifest file),包含每个版本的URL及其比特率。客户首先请求清单文件,获得不同版本的信息。然后,通过在HTTP GET请求报文中对每块指定URL和字节范围,来选择一个块。在下载块的同时,客户也测量接收带宽,并通过算法选择下次请求的块。DASH允许客户自由地在不同的质量等级之间切换。

对于Internet视频公司,提供流式视频服务最为直接的方法是:建立单一的大规模数据中心存储,并直接向全世界传输流式视频。但是这种方法存在三个问题。首先,如果客户远离数据中心,分组将跨越许多通信链路并通过许多ISP,某些ISP可能位于不同的大洲。如果这些链路之一提供的吞吐量小于视频码率,端到端吞吐量也将小于码率,给用户带来恼人的停滞。发生此情况的可能性随着端到端路径中链路数量的增加而增加。第二个缺陷是:热门视频会经过相同的通信链路发送许多次。这不仅严重浪费带宽,公司也需向ISP支付高昂的费用。第三个问题是:如果该数据中心故障,或其通向Internet的链路崩溃,公司将无法分发任何视频流。
目前,几乎所有主要的视频流公司都利用内容分发网络(Content Distribution Network,CDN)管理分布在多个地理位置上的服务器。服务器中存储视频(和其它Web内容,包括文档、图片和音频)的副本,并试图将每个用户请求定向到一个将提供最好的用户体验的CDN位置。CDN可以是专用的,即由内容提供商自己所拥有:例如,Google的CDN分发YouTube视频等内容;也可以是第三方CDN:Akamai、Limelight和Level-3都运行第三方CDN。

CDN通常采用两种不同的服务器安置原则:
·深入(Enter Deep)。该原则由Akamai首创:通过在遍及全球的接入ISP中部署服务器集群,来深入到ISP的接入网(1.3节)中。Akamai在至少数千个位置这样部署集群。其目标是靠近端用户,通过减少端用户和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的一个实例。
为了支持Google的巨量云服务:搜索、Gmail、日程表、YouTube视频、地图、文档和社交网络……,谷歌已经部署了一个遍布全球的专用网和CDN基础设施。谷歌的CDN基础设施具有3个等级的服务器集群:
·19个大型数据中心,位于北美、欧洲与亚洲,每个数据中心至少具有几十万台服务器。这些数据中心负责动态的(经常是个性化的)内容,包括搜索结果和Gmail报文。
·约90个集群分布于全球的一些IXP中,每个集群由不少于100 ~ 500台服务器组成。这些集群服务于静态内容,包括YouTube视频。
·在一些接入ISP中,每个包含数以百计的“深入(enter-deep)”集群。一个集群通常由一个机架上的数十台服务器组成。它们负责TCP splitting(见3.7节)并服务于静态内容,包括搜索结果的静态Web网页。
所有这些数据中心和集群与Google自己的专用网连接在一起。用户进行搜索时,搜索请求常常先经过本地ISP发送到邻近的“深入(Enter Deep)服务器”缓存中,从这里检索静态内容;其它邻近的缓存也将该静态内容提供给客户,经由Google的专用网将请求转发给大型数据中心,获得个性化的搜索结果。对于YouTube视频,它本身可能来自一个“请客(bring-home)”服务器缓存,而围绕该视频的Web网页部分可能来自邻近的“深入服务器”缓存,围绕该视频的广告来自数据中心。总的来说,除了本地ISP的那部分,Google云服务在很大程度上是由独立于公共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,在线访问):允许多个程序同时存取一个文件。和数据库不同,用户不需要调用特殊的客户进程,而是由操作系统提供对远地共享文件进行访问的服务,如同访问本地文件一样。这就使用户可以用远程文件直接作为输入和输出来运行任何应用程序,而操作系统中的文件系统则提供对共享文件的透明存取——将原来用于处理本地文件的应用程序用来处理远地文件时,一般不需要对该程序做出改动。

网络文件系统(Network File System,NFS)也属于文件共享协议。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)中,还有一个小而易于实现的简单文件传送协议(Trivial File Transfer Protocol,TFTP)。TFTP的版本2是互联网的正式标准。TFTP也使用C-S结构,但使用UDP,因此需要有自己的纠错措施。TFTP只支持文件传输而不支持交互。TFTP没有庞大的命令集,没有列目录的功能,也不能对用户进行身份鉴别。

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

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

TFTP发送完一个文件块就等待对方确认,确认时指明确认的块编号。发送完毕后,在规定时间内收不到确认,或者,接收方在规定时间内收不到下一个块,就要重发确认PDU。这样,文件传送不致因某份数据报的丢失而失败。
开始工作时,TFTP客户发送一个读(写)请求报文给服务器,端口为69。TFTP服务器进程要选择一个新的端口和TFTP客户进程通信。若文件长度为512字节的整数倍,则传送完毕后,必须再发送一份只含首部而无数据的报文。若文件长度不是512字节的整数倍,则最后一份数据报文中的数据字段不满512字节,正好作为EOF标志。

2.B TELNET
TELNET是一个简单的远程终端协议,它也是互联网的正式标准。用户用TELNET就可在其所在地通过TCP连接注册(登录)到远地的另一台主机上(使用主机名或IP地址)。TELNET能将用户的键盘输入传到远地主机,也将远地主机的输出通过TCP连接返回到用户屏幕。这种服务是透明的,因为用户感觉键盘和显示器好像直接连接到远地主机。因此,TELNET又名终端仿真协议。TELNET并不复杂,以前应用得很多。现在,由于计算机的功能越来越强,用户已较少使用TELNET了。
TELNET也使用C-S方式。本地系统运行TELNET客户进程,远地主机运行TELNET服务器进程(端口23)。和FTP的情况相似,服务器中的主进程等待新的请求,并产生从属进程来处理每一个连接。
TELNET能够适应许多计算机和操作系统的差异。例如:不同的系统用不同的方式刻画一行的结束(CR、LF、CRLF)。又如,在中断一个程序时,许多系统使用Ctrl+C(^C),但也有系统使用ESC。为了适应这种差异,TELNET定义了数据和命令怎样通过互联网。这些定义就是所谓的网络虚拟终端(Network Virtual Terminal,NVT)。下图说明了NVT的意义。客户端把用户的击键和命令转换成NVT格式,并送交服务器。服务器把收到的数据和命令从NVT格式转换成远地系统所需的格式。向用户返回数据时,服务器把远地系统的格式转换为NVT格式,本地客户再从NVT格式转换到本地系统所需的格式。

NVT的格式定义很简单。所有的通信都使用8位1字节。在运转时,NVT使用7位ASCII码传送数据;高位置1时,用作控制命令。ASCII码共有95个可打印字符(如字母、数字、标点符号)和33个控制字符。所有可打印字符在NVT中的意义和在ASCII码中一样。但NVT只使用了ASCII码的控制字符中的几个。此外,NVT还定义了两字符的CRLF为标准的行结束控制符。当用户键入回车时,TELNET客户把它转换为CRLF再进行传输,而TELNET服务器要把CRLF转换为远地机器的行结束符。
选项协商(Option Negotiation)使TELNET客户与服务器可商定更多的终端功能,协商的双方是平等的。
现在,许多用户现在更愿意采用SSH协议而不是Telnet,因为在Telnet连接中发送的数据(包括密码)是没有加密的,使得Telnet易于受到窃听。

2.C 搜索
在Web中用来进行搜索的工具叫做搜索引擎(search engine)。搜索引擎的种类很多,但大体上可分为两类,即全文检索搜索引擎和分类目录搜索引擎。
全文检索搜索引擎是一种纯技术型的检索工具。它的工作原理是:通过搜索软件,例如蜘蛛(spider)或爬虫(crawler),到各个网站收集信息。找到一个网站后,从这个网站再链接到另一个网站,像蜘蛛爬行一样。然后,按照一定的规则,建立一个很大的在线索引数据库供用户查询。查询时,只要输入关键词,就在建立的索引数据库里查询(并不是实时地在互联网上检索到的信息)。因此,查到的一些信息可能是过时已久的。建立这种索引数据库的网站,必须定期更新维护数据库,但不少网站的维护很不及时。所以,一定要注意查找到的信息的发布时间。全球最大、最受欢迎的全文检索搜索引擎就是Google。谷歌提供的主要的搜索服务有:网页、图片、视频、地图、新闻、购物、博客、论坛、学术、财经搜索等。应全球用户的需求,谷歌在世界各地建立数据中心。大多数数据中心的业主基于信息安全考虑,极少透露其数据中心的信息及内部情形。另外两个常用的全文检索搜索引擎分别是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还要进行超文本匹配分析,确定哪些网页与正在执行的搜索相关。综合考虑整体重要性和与查询的相关性之后,就把最相关、最可靠的搜索结果放在首位。
然而,某些知名网站通过“竞价排名”把虚假信息放在检索结果的首位,结果误导了消费者,使之蒙受巨大损失。对网络搜索的结果,应认真分析真伪、提高辨别能力,不要轻信检索的广告信息(哪怕是知名度很高的网站)。 
  • 0
    点赞
  • 1
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值