《计算机网络(英文版·第5版)》 The Application Layer
DNS —— Domain Name System, 域名系统
DNS 的本质是发明了一种层次的、基于域名的命名方案,并且用一个分布式数据库系统加以实现
DNS 的主要用途是将主机名映射成 IP 地址
DNS 的使用方法:
- 为了将一个名字映射成 IP 地址,应用程序调用一个名为解析器(resolver)的库程序,并将名字作为参数传递给此程序
- 解析器向本地 DNS 服务器发送一个包含该名字的请求报文;本地 DNS 服务器查询该名字,并返回一个包含该名字对应IP地址的响应报文给解析器,然后解析器再将IP地址返回给调用方
- 查询报文和响应报文都作为 UDP 数据包发送
- 有了 IP 地址以后,应用程序就可以与目标主机建立一个 TCP 连接,或者给它发送 UDP 数据包
DNS 名字空间
对于 Internet,命名层次结构的顶级由 Internet 名字与数字地址分配机构(ICANN, Internet Corporation for Assigned Names and Numbers)
从概念上讲,Internet 被划分为超过 250 个顶级域名(top-level domains),其中每个域涵盖了许多主机
- 这些域又被进一步划分成子域,这些子域可被再次划分
顶级域名分为两种类型:
- 通用的(generic): 3 字符的码表示了功能
- 主要用于美国
- 比如:gov, mli, edu, org, com, net
- 国家或地区的(countries): 2 字符的国家/地区(region)码
- 包括每个国家或地区,由 ISO 3166 文档定义
- au, jp, uk, us, nl
通用的顶级域名
域名与金钱挂钩
- 域名抢注(cybersquatting)
域名
每个域的名字是由它向上到(未命名的)根节点的路径来命名的,路径上的各个部分用句点(dot)分开
域名可以是绝对的,也可以是相对的。绝对域名总是以句点作为结束,而相对域名必须在一定的上下文环境中被解释才有真正的含义
域名不区分大小写,因此 edu、EDU、Edu 的含义都一样。各组成部分的名字最多可以有 63 个字符,整个路径的名字不超过 255 个字符
每个域自己控制如何分配它下面的子域
- 为了创建一个新域,创建者必须得到包含该新域的上级域的许可。一旦创建并注册了一个新域,则该新域就可以创建属于自己的子域,而无须得到域名树中任何上层域的许可
命名机制遵循的是以组织为边界,而不是以物理网络为边界
- 即使使用同一个 LAN,两个组织也可以属于完全不同的域
- 也可以在两个不同的地方,但这两个地方的主机属于同一个域
域名资源记录(resource record)
无论是只有一台主机的域还是顶级域,每个域都有一组与它相关联的资源记录
- 这些记录组成了 DNS 数据库
一条资源记录是一个五元组
- Domian_name(域名):指出了这条记录适用于哪个域
- Time_to_live(生存期):指明了该条记录的稳定程度
- Class(类别):对于 Internet 信息,总是 IN
- Type(类型):指出了这是什么类型的记录
- Value(值):可以是一个数字、一个域名或一个 ASCII 字符串,其语义取决于记录的类型
主要的 DNS 资源记录类型
- A(地址)记录,包含了某台主机一个网络接口的 32 位地址
- NS 记录,指明了一台用于所在域和子域的名字服务器(拥有一份某域数据库副本的主机)
- CNAME 记录,宏定义(可以用另一个串来替代一个串),允许创建别名
- PTR 指向另一个名字,正规的DNS数据类型,确切含义取决于上下文
域名服务器
理论上,一台域名服务器可以包含整个 DNS 数据库,并响应所有对该数据库的查询
- 实际上,这台服务器会负载过重,一旦停机,整个 Internet 将会瘫痪
为避免由于单个信息源带来的各种问题,DNS 命名空间被划分为一些不重叠的区域(zones)
- 每个圈起来的区域包含域名树的一部分,并且还包含域名服务器(包含有关该区域的信息)
域名和域
- 每个域都被标记为域中的特定的节点
- 一个 DNS 域名是命名空间下的一个分支
- 一个域是 DNS 命名空间的一部分,被存储在文件中(包含许多节点)
- 一个服务器可以把它的域划分,并将它分发其他服务器
区域边界应该放置在区域中的什么位置由该区域的管理员来决定。这个决定在很大程度上取决于需要在哪里使用多少个域名服务器
每个区域都与一个或多个域名服务器关联。这些服务器是持有该区域数据库的主机
- 通常情况下,一个区域有一个主域名服务器和一个或多个辅域名服务器。主服务器从自己磁盘的一个文件读入有关域名信息,辅域名服务器从主域名服务器获取域名信息
- 为了提高可靠性,一些域名服务器可以设置在区域外面
- 添加一个主机
- 当一个新主机加入该域,管理员将 IP 和名字写入主域名服务器的配置文件中
查询一个名字和找出其对应地址的过程称为域名解析(name resolution)
- 当解析器需要查询一个域名,它就把该查询传递给一个本地服务器
- 如果需要寻找的域恰好落在该域名服务器管辖下,则该域名服务器就返回权威资源记录
- 一个权威记录(authoritative record)由管理该记录的权威部门提供,因此总是正确的
- 权威记录的权威性是相对缓存记录(cached record)而言的,缓存的记录有可能过时
- 如果被查询域在远端,如果本地没有关于相关域的缓存信息,那么域名服务器启动一次远程查询
解析器(resolver)和域名服务器
- 主机上的一个应用程序通过一个 DNS 客户端(解析器)来访问域名服务器
- 解析器访问 DNS 服务器,叫做域名服务器
- DNS 服务器返回 IP 地址,解析器将 IP 地址返回应用
- 相反的查找也是可以的,通过 IP 地址查找名字
解析器查询一个远程域名的 10 个步骤
- UW 华盛顿大学
- 查询报文被发送带本地域名服务器。查询中包含了被查询的域名、类型(A)和类别(IN)
- 通过请求其中之一的根域名服务器来启动域名层次结构顶部的查询。这些域名服务器包含每个顶级域名的有关信息
- 为了与一个根服务器取得联系,每个域名服务器必须有一个或多个根域名服务器的信息
- 则个信息通常放在一个系统配置文件中,在 DNS 服务器启动时把该文件加载到 DNS 缓存
- 这个文件很简单,只是列出了关于根服务器的 NS 记录和相应的 A 记录
- 根域名服务器(它知道 edu 域的域名服务器)返回查询的答案,其中包括了名字和 IP 地址
- 本地域名服务器将整个查询发给 edu 域名服务器
- edu 域名服务器返回 UW 的域名服务器(washington.edu)
- 本地域名服务器把查询发给 UW 的域名服务器
- 如果 CS 运行的是自己的域名服务器,此查询返回的是 CS 的域名服务器和 IP 地址
- 本地域名服务器查询 CS 的域名服务器
- CS 的域名服务器返回最终答案,发到本地域名服务器
- 本地域名服务器将最终结果转发给主机
两种不同的查询机制
- 由 DNS 请求中的 1 个 bit 决定
- 当主机将查询发给本地域名服务器后,域名服务器就代替主机处理域名解析工作,直到它返回所需的答案
- 这里的答必须是完整的,它不能返回部分答案
- 这个机制称为递归查询(recursive query)
- 根域名服务器(和每个后续的域名服务器)并不是递归查询本地域名服务器。它只是返回一个部分答案,并移动到下一个查询操作。本地域名服务器负责继续解析,具体做法是发出进一步的查询报文
- 这个机制称为迭代查询(iterative query)
递归查询
- 当主机的域名服务器无法解析查询时,服务器发出一个查询来解析查询
迭代查询
- 当主机的域名服务器无法解析查询时,它将一个引用传递给另一个服务器给解析器
一次域名解析可以涉及两种机制。递归查询似乎总是可取的,但许多域名服务器(尤其是跟服务器)并没有采用这种方式,迭代查询则将重负给查询发起方。本地域名服务器支持递归查询的理由是它负责为其域内的主机提供服务。这些主机不必配置成运行一个完整的域名服务器,它们只要刚好能到达本地域名服务器即可
所有的查询答案,包括所有的部分答案都会被缓存。使用缓存答案的做法可大大降低依次查询的步骤,并能提高查询性能
- 高速缓存的答案不具权威性,因此缓存的表项不应该生存得太长
- 资源记录中的
Time_to_live
字段
关于查询和响应使用的传输层协议。域名系统采用的是 UDP
- DNS 消息通过 UDP 数据包发送,格式非常简单,只有查询和响应;域名服务器可用此数据包继续进行解析操作
- 如果在很短的时间内没有响应返回,DNS 客户端必须重复查询请求;如果重复一定次数后仍然失败,则尝试域内另一台域名服务器
- 查询过程这样设计的主要目的是为了应付出现服务器关闭以及查询或响应包丢失的情况
- 每个查询报文都包含 16 位的标识符,这个标识符将被复制到响应包中,以便域名服务器将接收到的答案与相应的查询匹配,即使它同时发出了多个查询也不会混淆查询结果
13 个根域名服务器
被本地域名服务器查询,并且不能解析名字
根域名服务器
- 如果名字映射未找到,联系权威域名服务器
- 获得映射
- 返回映射给本地域名服务器
每个根服务器可以是逻辑上的一台计算机。然而,由于整个 Internet 依赖于根服务器,因此它们必须是能力超强的,并且被大量复制的计算机
大多数服务器被放置在多个地理位置,查询报文通过 选播 / 任播 路由到达其中一台服务器
- 选播是一种特殊的路由,它能将数据包路由到最近的一个目标地址实例
- 复制技术能提高域名系统的可靠性和性能
9 个服务器使用一种称为选播(任播, anycast)的路由技术在多个地理位置运行,提高性能并容忍更多的错误
为了提高性能和可靠性,还利用了复制和缓存机制,同时设计得具有很强的鲁棒性
- 减少 DNS 流量,域名服务器缓存
域名 - IP
的映射信息- 缓存条目在一段时间后超时(消失)
- 当查询条目位于缓存中时,服务器不会联系其他服务器
- 注意:如果从缓存发送条目,则来自服务器的回复将被标记为“未授权”
- DNS 使用 53 端口
安全机制 DNSSEC,DNS 的安全扩展,防止改变域名到地址的映射
内容分发网络:首先对内容进行命名,然后解析出拥有该内容的附近一个主机的 IP 地址。这种映射模式特别符合搜索一个电影并下载它的应用模式(解析所要的全部结果只是附近具有该影片拷贝的任何一台计算机 IP 地址)
Electronic Mail*
体系结构和服务
包括两类子系统:
- 用户代理(user agent)
- 邮件传输代理(message transfer agent)
- 非正式地称作邮件服务器
用户代理是一个程序,用户通过它与电子邮件系统交互
邮件传输代理通常是系统进程,采用的协议是简单邮件传输协议 SMTP(Simple Mail Transfer Protocol)
用户代理
用户代理是一个程序(电子邮件阅读器),它接受各种各样的命令,从接收和回复邮件到操纵邮箱的命令
邮件格式
RFC 5322 —— Internet 邮件格式
- 邮件由一个基本的信封、数个头字段、一个空行和邮件体组成
与邮件传输相关的主要头字段
MIME —— 多用途 Internet 邮件扩展
Multipurpose Internet Mail Extensions
MIME 的基本思想是继续使用 RFC 822 格式,但在邮件体中增加了结构性,并且为传送非 ASCII 码的邮件定义了编码规则
MIME 定义了 5 种新的邮件头
类型以及相关的常用子类型
邮件传送
邮件传送采用的协议是 SMTP(简单邮件传输协议 Simple Mail Transfer Protocol)
- 在Internet上,发送电子邮件的计算机首先与目标计算机的 25 端口建立一个 TCP 连接。然后在此连接上传送电子邮件
- 服务器接收入境连接请求,执行某些安全检查,并接受传递过来的邮件
- 如果一个邮件无法被投递,则向邮件发送方返回错误报告
SMTP 是一个简单的 ASCII 协议
- 使用 ASCII 文本。使得协议更加易于开发、测试和调试
- 通过手动发送命令就可以进行测试,记录的消息易于阅读
- HTTP 也以这种方式工作
SMTP 的不足
- SMTP 不包括认证:垃圾邮件
- 传输的是 ASCII 消息而不是二进制数据:需要 Base64 MIME 内容传送编码方案
- SMTP 发送的邮件以明文形式出现
邮件传送
- 一旦接收到来自用户代理发送的邮件,邮件传输代理便使用 SMTP 将该邮件传送给接收邮件传输代理
- 为了确定要联系的正确邮件服务器,必须咨询 DNS
最后传递
SMTP 是一种基于推(push-based)的协议,它获取一个邮件,并且连接到远程服务器来传递邮件。邮件的最终交付不能以这种方式实现,因为
- 邮件传输代理上的邮箱必须可以连续存储
- 用户代理可能在 SMTP 视图中继邮件的那一刻无法连接到 Internet 上
IMAP —— Internet邮件访问协议
Internet Message Access Protocol
为了使用 IMAP,邮件服务器必须运行 IMAP 服务器,它负责监听 143 端口
IMAP 是较早使用的最终交付协议 —— 邮局协议版本3(POP3, Post Office Protocol, version 3)的改进版
- POP3 监听 110 端口
Webmail
- 许多 Webmail 的实现使用 IMAP 从服务器检索电子邮件并在 Web 浏览器中显示它们,使得此协议的使用对用户透明
WWW —— World Wide Web
Web 是万维网(World Wide Web)的俗称,它是一个体系结构框架。该框架把分布在整个 Internet 数百万台机器上的内容链接起来供人们访问
万维网联盟(W3C, World Wide Web Consortium)
体系架构概述
Web 页面(Web Pages)或简称为页面(page)
- 内容以页面的形式表示
超文本(Hypertext)
- 让一个页面指向另一个页面
超链接(Hyperlinks)
- 与另一个页面相关的一小段文字、一个图标、一个图像等
HTML
- 超文本标记语言
浏览器(Browser)
- 浏览器取回请求的页面,对页面内容进行解释,并在屏幕上显示
页面显示的基本工作模型
客户端
在显示一个被选中的页面之前,首先必须回答3个问题
- 这个页面叫什么
- 这个页面在哪里
- 如何访问这个页面
当用户点击一个超链接,浏览器就执行一系列的步骤来获取该超链接指向的网页
- 浏览器确定 URL
- 浏览器请求 DNS 查询服务器的 IP 地址
- DNS 返回 IP 地址
- 浏览器与 IP 地址对应的机器的 80 端口建立一个 TCP 连接,80 端口是 HTTP 协议的知名端口(famous ports)
- 浏览器发送 HTTP 报文,请求页面
- 服务器返回页面作为 HTTP 响应
- 如果该页面包括需要显示的 URL,那么浏览器经过同样的处理过程获取其他 URL
- 浏览器显示页面
- 如果短期内没有向同一个服务器发出其它请求,就释放 TCP 连接
URL(Uniform Resource Locator, 统一资源定位符)包括三个部分
- 协议(也称为方案(scheme))
- 页面所在机器的 DNS 名字
- 唯一指向特定页面的路径
URL 设计是开放式的,在某种意义上它很简单,允许浏览器使用多种协议去获得各种不同的资源
URI(Uniform Resource Identifiers, 统一资源标识符)
- 某些 URI 告诉浏览器如何定位资源,就是 URL;其他 URI 告诉了资源名字,但没有说明哪里可以找到它,这些 URI 就称为统一资源名(Uniform Resource Names)
MIME 类型
有两种可能的方式,插件和辅助应用程序
- 插件(plug-in)是一个第三方代码模块,作为扩展(extension)被安装到浏览器中
- 辅助应用程序(helper application)是一个作为独立进程运行的完整程序
服务器端
服务器在主循环中执行如下步骤
- 接受来自客户端(浏览器)的 TCP 连接
- 获取页面的路径,即被请求文件的名字
- 获取文件(从磁盘上)
- 将文件内容发送给用户
- 释放该 TCP 连接
现代 Web 服务器具有更多的功能,但本质上这就是 Web 服务器在最简单情况下所作的工作,即获取一个包含网页内容的文件
对于动态内容,第 3 步必须替换成运行一个程序(由路径决定),该程序性能返回网页的内容
多线程模式(multiithreaded)服务器
在其中一种设计方案中,服务器由一个前端模块(front-end module)和 k 个处理模块组成
- 解析被请求的 Web 页面的名字
- 执行对该页面的访问控制
- 检查缓存
- 从磁盘上获取请求的页面或者运行一个创建页面的程序
- 确定响应中的剩余部分(比如要发送的MIME类型)
- 把响应返回给用户
- 在服务器的日志中增加一个表项
Cookie
网络基本上是无状态的
- 没有登录会话的概念。浏览器发送一个请求服务器,并获得返回的文件。然后,服务器彻底忘记它已经看到过哪些特定的客户
问题
- 区分注册用户
- 电子商务中跟踪客户
- 定制的门户网站
RFC 2109 / RFC 2965
- 当客户请求一个 Web 页面时,服务器除了提供所请求的页面以外,还以 Cookie 的形式提供了一些附加的信息
- Cookie 是一个相当小的命名的串(最多 4 KB),服务器将它与浏览器关联。浏览器把服务器所提供的 Cookie 通常存储在客户机磁盘 Cookie 目录下一段时间,这样在整个浏览器调用期间一直坚持 Cookie,除非用户禁用 Cookie
Cookie 字段
域(domain)
- 指出 Cookie 来自何方
路径(path)
- 服务器目录结构中的一个路径,它标识了服务器文件树的哪些部分可能使用该 Cookie
- 路径通常是
/
,意味着整棵树
内容(content)
- 采用
名字=值
的形式,Cookie 的名称 = Cookie 保存的文本值
过期时间(expires)
- 指定了该 Cookie 何时过期
- 非持续(nonpersistent):在浏览器退出时丢弃 Cookie
- 持续(persistent):针对 Cookie 提供了时间和日期
安全(secure)
- 指示浏览器只向使用安全传输连接的服务器返回 Cookie
- 安全传输就是 SSL/TLS
例子
如何使用 Cookie
- 在浏览器向某个 Web 站点发出一个页面请求之前,浏览器检查它的 Cookie 目录,确定这个请求前往的目标域是否在当前客户端放置了 Cookie
- 如果存在相应的 Cookie,则该域放置的所有 Cookie 都被包含到请求消息中。服务器得到了这些 Cookie 以后,就可以按它所期望的方式来解释它们
Cookie 与会话 ID(Session ID)
- 用户 ID 或 Session ID(一个长字符/唯一分配的字符串)通常存储在 Cookie 中。在存储关于用户或会话的信息时,会话 ID 被用作密钥或标识符
- 例如,用户登录到一个站点。如果用户名和密码匹配,则服务器在浏览器中设置一个包含会话 ID 的 Cookie(
Set-Cookie
); 服务器还会在网站数据库中存储一个将会话 ID 映射到用户名的条目。当 Cookie 被返回时,将读取会话标识并在数据库中查找用户名
静态 Web 页面
HTML (HyperText Markup Language) —— 超文本标记语言
- HTML 允许用户生成一个包含了文本、图形和指向其他 Web 页面指针的 Web 页面
- HTML 是一种标记语言,或一种描述了如何格式化文档的语言
动态 Web 页面和 Web 应用*
公共网关接口(CGI, Common Gateway Interface)
超文本预处理器(PHP, Hypertext Preprocessor)
AJAX 异步 JavaScript 和 XML(Asynchronous JAvascript and Xml)
文档对象模型(DOM, Document Object Model)
可扩展标记语言(XML, eXtensible Markup Language)
用来生成动态页面的不同技术
HTTP —— 超文本传输协议
The HyperText Transfer Protocol
一个简单的请求-响应协议,通常运行在 TCP 上
制定了客户端可能发送给服务器什么样的消息以及得到什么样的响应
请求-响应模型
HTTP 具有简单的结构
- 客户端发送 ASCII 请求消息
- 服务器返回应答消息(类似 MIME)
HTTP 可以通过单个 TCP 连接支持多个请求-应答交换
连接
- 浏览器与服务器联系最常用的方法是与服务器机器上的端口 80 建立一个 TCP 连接
HTTP1.0(a)
HTTP1.1(b,c)
- 持续连接(persistent connection)/ 连接重用(connection reuse)
- (a)单独连接单独请求
- (b)持续连接,单独请求
- (c)持续连接,连续请求(pipelling)
并行连接(parallel connection)
- 在每个 TCP 连接上发送一个请求,但同时并行打开多个 TCP 连接
方法(method)
- GET / POST
响应组的状态码
HTTP 消息
每条消息,无论是请求或是响应,都有三个部分
- 请求或响应行(request or response line )
- 头(header section)
- 消息正文(body of the message)
消息头
- 请求头(request header)/响应头(response header)
缓存(caching)
- 优点是当缓存页面重复使用时没必要进行重复传输,减少网络流量和延迟,从而提高性能
- 困难是如何确定缓存是否要更新
总结
HTTP 是一个非常简单的协议,它有很多种可能的预定义头信息
- 只要客户端和服务器同意,就可以添加更多的类型
客户端的请求由三部分组成
- 标题行(header line)
- 包含头信息的块,以空行结束(header information)
- 包含数据的(可选)实体主体(entity body)
服务器的响应也由这三部分组成