计算机网络(二)

第2章 应用层

2.1 应用层协议原理

网络核心设备(如路由器或链路层交换机)并不在应用层起作用,而仅在较低层起作用,特别是在网络层及其下面层次起作用。

我们不需要为网络核心设备写应用软件,我们也做不到这一点。

这种将应用软件限制在端系统的方法,促进了大量网络应用程序的迅速研发和部署。

2.1.1 网络应用程序体系结构

应用程序体系结构(application architecture) 由应用程序研发者设计,规定了如何在各种端系统上组织该应用程序。

应用程序的体系结构明显不同于网络的体系结构。

从应用程序研发者的角度看,网络体系结构是固定的,并为应用程序提供了特定的服务集合。

现代网络应用程序中所使用的两种主流体系结构:

  • 客户—服务器体系结构
  • P2P体系结构

客户—服务器体系结构(client-server architecture)

有一个总打开的主机称为 服务器 ,它服务于许多其他称为 客户 的主机。

配备大量主机的 数据中心(data center) 常被用于创建强大的虚拟服务器。

特点:

  1. 客户相互之间不直接通信
  2. 该服务器具有固定的、周知的地址,即 IP 地址。

应用程序:

  • Web

  • FTP

  • Telnet

  • 电子邮件

P2P体系结构(P2P architecture)

对位于数据中心对的专用服务器有最小的(或没有)依赖。

应用程序在断联的主机对之间使用直接通信,这些主机对被称为对等方。

特点:

  1. 子扩展性(self-scalability):

    在一个 P2P 文件共享应用中,每个对等方由于请求文件产生工作负载,通过向其他对等方分发文件也为系统增加服务能力。

应用:

  • 文件共享(例如 BitTorrent)
  • 对等方协助下载加速器(例如迅雷)
  • 因特网电话和视频会议(例如 Skype)

2.1.2 进程通信

用操作系统的术语来说,进行通信的实际上是 进程(process) 而不是程序。

  1. 当一个程序运行在 相同的 端系统上时,在操作系统确定的进程间通信规则下相互通信。
  2. 在两个 不同的 端系统上的进程,通过跨越计算机网络交换 报文(message) 而相互通信。

1.客户和服务器进程

在一对进程之间的通信会话场景中,发起通信的进程被标识为 客户 ,在会话开始时等待联系的进程是 服务器

  • Web 中,浏览器是一个客户进程,Web 服务器是一个服务器进程。
  • P2P 文件共享,下载文件的对等方标识为客户,上传文件的对等方标识为服务器。

2.进程与计算机网络之间的接口

进程通过一个称为 套接字(socket) 的软件接口向网络发送报文和从网络接收报文。

如果把进程视为一间房子,那么套接字就是门,门外通过特定的交通方式运输。

套接字是同一台主机内应用层与运输层之间的接口。

由于该套接字是建立网络应用程序的可编程接口,因此该套接字也称为应用程序和网络之间的 应用程序编程接口(Application Programming Interface, API)

3.进程寻址

为了表识接收进程,需要定义两种信息:

  1. 主机的地址:在因特网中,主机由其 IP地址(IP address) 标识。
  2. 在目的主机中指定接收进程的标识符: 端口号(port number) 用于指定运行在接收主机上的接收进程(更具体地说,接收套接字)。

流行的应用分配了特定的端口号:

Web 服务器用端口号 80 来标识。

邮件服务器进程(使用 SMTP 协议)用端口号 25 来标识。

用于所有因特网标准协议的周知端口号的列表能够在 http:///www.iana.org 处找到。

2.1.3 可供应用程序使用的运输服务

当开发一个应用时,必须选择一种可用的运输层协议。

一个运输层协议能够为应用程序提供的服务可分为如下 4 类:

  1. 可靠数据传输
  2. 吞吐量
  3. 定时
  4. 安全性

2.1.4 因特网提供的运输服务

因特网(更一般的是 TCP/IP 网络)为应用程序提供两个运输层协议,即 UDP 和 TCP 。

1. TCP 服务

TCP服务模型包括面向连接服务和可靠数据传输服务。

  • 面向连接的服务:在应用层数据报文开始流动之前,TCP 让客户和服务器互相交换运输层控制信息。这个握手过程是提醒客户和服务器,让它们为大量分组的到来做好准备。在握手阶段后,一个 TCP 连接(TCP connection) 就在两个进程的套接字之间建立了。这条连接是全双工的,即连接双方的进程可以在此连接上同时进行报文收发。

  • 可靠的数据传输服务:通信进程能够依靠 TCP ,无差错、按适当顺序交付所有发送的数据。

TCP 协议具有拥塞控制机制,这种服务不一定能为进程通信带来直接好处,但能为因特网带来整体好处。TCP 拥塞控制也试图限制每个 TCP 连接,使它们达到公平共享网络带宽的目的。

SLL 不是与 TCP 和 UDP 在相同层次上的第三种因特网运输协议,而是一种对 TCP 的加强,这种强化是在应用层上实现的。

2. UDP 服务

一种不提供不必要服务的轻量级运输协议,它仅提供最小服务。

UDP 是无连接的,因此在两个进程通信前没有握手过程。 UDP 协议提供一种不可靠数据传输服务。到达接收进程的报文也可能是乱序到达的。

UDP 没有拥塞控制机制,所以 UDP 的发送端可以用它选定的任何速率其下层(网络层)注入数据。

2.1.5 应用层协议

应用层协议(application-layer protocol) 定义了运行在不同端系统上的应用程序进程如何相互传递报文。特别是定义了:

  • 交换的报文类型,例如请求报文和响应报文。
  • 各种报文类型的语法,如报文中的各个字段及这些字段是如何描述的。
  • 字段的语义,即这些字段中的信息的含义。
  • 确定一个进程何时以及如何发送报文,对报文进行响应的规则。

2.2 Web 和 HTTP

Web是一个因特网应用。

对大多数用户,最有吸引力的就是 Web 的按需操作。

2.2.1 HTTP 概况

Web 的应用层协议是 超文本传输协议(HyperText Transfer Protocol, HTTP) ,它是 Web 的核心。

HTTP 由两个程序实现:

  1. 一个客户程序
  2. 一个服务器程序

客户程序和服务器程序运行在不同的端系统中,通过交换 HTTP 报文进行会话。

HTTP 定义了这些报文的结构以及客户和服务器进行报文交换的方式。

Web 页面(Web page) (也叫文档)是由对象组成的。一个 对象(object) 只是一个文件,诸如一个 HTML 文件、一个 JPEG 图形、一个 Java 小程序或一个视频片段这样的文件,而且它们可以通过一个 URL 地址寻址。多数 Web 页面含有一个 HTML 基本文件(base HTML file) 以及几个引用对象。

例如,如果一个 Web 页面包含 5 个 JPEG 图形,那么这个 Web 页面有 6 个对象:一个 HTML 基本文件和 5 个图形。

HTML 基本文件通过对象的 URL 地址引用页面中的其他对象。每个 URL 地址由两部分组成:

  • 存放对象的服务器主机名
  • 对象的路径名

例如,URL 地址 http://www.someSchool.edu/someDepartment/picture.gif ,其中 www.someSchool.edu 就是主机名, /someDepartment/picture.gif 就是路径名。

Web 浏览器(Web browser) (例如 Internet Exploer 和 Firefox)实现了 HTTP 的客户端。

Web 服务器(Web server) 实现了 HTTP 的服务器端,用于存储 Web 对象,每个对象由 URL 寻址。流行的 Web 服务器有 Apache 和 Microsoft Internet Information Server (微软互联网信息服务器)。

HTTP 使用 TCP 作为它的支撑运输协议(而不是在 UDP 上运行)。

由于 HTTP 服务器并不保存关于客户的任何信息, HTTP 是一个 无状态协议(stateless protocol) 。Web 服务器总是打开的,具有一个固定的 IP 地址,且它服务于可能来自数以百万计的不同浏览器的请求。

2.2.2 非持续连接和持续连接

非持续性连接(non-persistent connection)

每个请求/响应对是经一个单独的 TCP 连接发送

请求/访问过程如下:

  1. HTTP 客户进程在特定端口号发送一个到服务器的 TCP 连接。在客户和服务器上分别有一个套接字与该连接相关联。
  2. HTTP 客户经它的套接字向该服务器发送一个 HTTP 请求报文。
  3. HTTP 服务器进程经他的套接字接收请求报文,从其存储器(RAM 或磁盘)中检索出对象,在一个 HTTP 响应报文中封装对象,并通过其套接字向客户发送响应报文。
  4. HTTP 服务器进程通知 TCP 断开该 TCP 连接。(但是直到 TCP 确认客户已经完整地收到响应报文为止,它才会实际中断连接。)
  5. HTTP 客户接收响应报文,TCP 连接关闭。
  6. 对每个引用对象重复前 4 个步骤。

往返时间(Round-Trip Time,RTT) 的定义是,一个短分组从客户到服务器然后再返回客户所花费的时间。

”三次握手“ 过程如下:

  1. 客户向服务器发送一个小 TCP 报文段。
  2. 服务器用一个小 TCP 报文段做出确认和响应。
  3. 最后,客户向服务器返回确认。(客户结合这部分向该 TCP 连接发送一个 HTTP 请求报文。)

缺点:

  1. 必须为每一个请求的对象建立和维护一个全新的连接。

    对于每个这样的连接,在客户和服务器中都要分配 TCP 的缓冲区和保持 TCP 变量,这给 Web 服务器带来了严重的负担。

  2. 每一个对象经受两倍 RTT 的交付时延,即一个 RTT 用于建立 TCP ,另一个 RTT 用于请求和接收一个对象。

持续性连接(persistent connection)

在采用 HTTP 1.1 持续连接的情况下,服务器在发送响应后保持该 TCP 连接打开。在相同的客户和服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。

HTTP 在其 默认方式 下使用 持续性连接

一般来说,如果一条连接经过一定时间间隔(一个可配置的超长时间间隔)仍未被使用,HTTP 服务器就关闭该连接。

2.2.3 HTTP 报文格式

1. HTTP 请求报文

HTTP 请求报文的第一行叫做 请求行(request line) ,其后继的行叫作 首部行(header line)

请求行有 3 个字段:

  1. 方法字段:包括 GET、POST、HEAD、PUT 和 DELETE。
  2. URL 字段
  3. HTTP 版本字段。

首部行:

  • Host: www.someschool.edu 指明了对象所在的主机、

  • Connection: close 该浏览器告诉服务器不要麻烦地使用持续连接,要求服务器发送完被请求的对象后就关闭这条连接。

  • User-agent: Mozilla/5.0 这里是浏览器类型,即 Firefox 浏览器。

    这个首部行有用,因为服务器可以有效地为不同类型的用户代理实际发送相同对象的不同版本(每个版本由相同的 URL 寻址)。

  • Acept-language: fr 用户想得到该对象的法语版本,如果服务器中没有这样的对象,则发送默认版本。

一个 HTTP 请求报文的通用格式如下:

首部行(和附加的回车和换行)后有一个”实体体“(entity body)。使用 GET 方法时实体体为空,而使用 POST 方法时才应用该实体体。

使用 POST 报文时,用户仍可以向服务器请求一个 Web 页面,但 Web 页面的特定内容依赖于用户在表单字段中输入的内容。如果方法字段的值为 POST 时,则实体体中包含的就是用户在表单字段中的输入值。

HTML 表单经常使用 GET 方法,并在(表单字段中)所请求的 URL 中包括输入的数据。例如,一个表单使用 GET 方法,它有两个字段,分别填写的是”monkeys“和”banana“,这样,该 URL 结构为 www.somesite.com/animalsearch?monkeys&bananas

HEAD 方法类似于 GET 方法。当服务器收到一个使用 HEAD 方法的请求时,将会用一个 HTTP 报文响应,但是并不返回请求对象。应用程序开发者常用 HEAD 方法进行调试跟踪。

PUT 方法常与 Web 发行工具联合使用,它允许用户上传对象到指定的 Web 服务器上指定的路径(目录)。

DELETE 方法允许用户或者应用程序删除 Web 服务器上的对象。

2. HTTP 响应报文

该响应报文有三个部分:

  1. 初始状态行(status line):3 个字段(协议版本字段、状态码和相应状态信息)
  2. 6 个首部行(header line):
    • Connection: close 告诉客户,发送完报文后将关闭该 TCP 连接
    • Date:首部行指示服务器产生并发送该响应报文的日期和时间。这个时间不是对象创建或者最后修改的时间,而是服务器从它的文件系统中检索到该对象,将该对象插入响应报文,并发送该响应报文的时间。
    • Server:首部行指示该报文是由一台 Apache Web 服务器产生的,它类似于 HTTP 请求报文中的 User-agent:首部行。
    • Last-Modified:首部行指示了对象创建或者最后修改的日期和时间。
    • Content-Length:首部行指示了被发送对象中地字节数。
    • Content-Type:首部行指示了该实体对象是 HTML 文本。
  3. 实体体(entity body):报文的主要部分,包含了请求的对象本身(表示为 data data data data data …)。

响应报文的通用格式如下:

状态码及其相应的短语指示了请求的结果。一些常见的状态码和相关的短语包括:

  • 200 OK:请求成功,信息在返回的响应报文中。
  • 301 Moved Permanently:请求的对象已经被永久转移了,新的 URL 定义在响应报文的 Location:首部行中。客户软件将自动获取新的 URL。
  • 400 Bad Request:一个通用差错代码,只是该请求不能被服务器理解。
  • 404 Not Found:被请求的文档不在服务器上。
  • 505 HTTP Version Not Supported:服务器不支持请求报文使用 HTTP 版本。

HTTP 使用了 cookie ,它允许站点对用户进行跟踪。目前大多数商务 Web 站点都使用了 cookie 。

如下图,cookie 技术有 4 个组件:

  1. 在 HTTP 响应报文中的一个 cookie 首部行;
  2. 在 HTTP 请求报文中的一个 cookie 首部行;
  3. 在用户端系统中保留有一个 cookie 文件,并由用户的浏览器进行管理;
  4. 位于 Web 站点的一个后端数据库。

cookie 可以用于标识一个用户。用户首次访问一个站点时,可能需要提供一个用户标识(可能是名字)。在后继会话中,浏览器向服务器传递一个 cookie 首部,从而向该服务器标识了用户。因此 cookie 可以在无状态的 HTTP 之上建立一个用户会话层。

结合 cookie 和用户提供的账户信息,Web 站点可以知道许多有关用户的信息,并可能将这些信息卖给第三方。有隐私被侵害的风险。

2.2.5 Web 缓存

Web 缓存器(Web cache) 也叫 代理服务器(proxy server) ,它是能够代表初始 Web 服务器来满足 HTTP 请求的网络实体。Web 缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象的副本。如下图,可以配置用户的浏览器,使得用户的所有 HTTP 请求首先指向 Web 浏览器。

例: 假设浏览器正在请求对象 http://www.someschool.edu/campus.gif ,将会发生如下情况:

  1. 浏览器创建一个到 Web 缓存器的 TCP 连接,并向 Web 缓存器中的对象发送一个 HTTP 请求。
  2. Web 缓存器进行检查,看看本地是否存储了该对象副本。如果有,Web 缓存器就向客户浏览器用 HTTP 响应报文返回该对象。
  3. 如果 Web 缓存器中没有该对象,它就打开一个与该对象的初始服务器(即 www.someschool.edu)的 TCP 连接。Web 缓存器则在这个缓存器到服务器的 TCP 连接上发送一个该对象的 HTTP 请求。在收到该请求后,初始服务器向该 Web 缓存器发送具有该对象的 HTTP 响应。
  4. 当 Web 缓存器接收到该对象时,它在本地存储空间存储一份副本,并向客户的浏览器用 HTTP 响应报文发送该副本(通过现有的客户浏览器和 Web 缓存器之间的 TCP 连接)。

Web 缓存器通常由 ISP 购买并安装。例如,一所大学可能在它的校园网上安装一台缓存器,并且将所有校园网上的用户浏览器配置为指向它。

在因特网上部署 Web 缓存器的两大优点:

  1. Web 缓存器可以大大减少对客户请求的的响应时间。
  2. Web 缓存器能够大大减少一个机构的接入链路到因特网的通信量。

通过使用 内容分发网络(Content Distribution Network,CDN),Web 缓存器正在因特网中发挥越来越大的作用。CDN 公司在因特网上安装了许多地理上分散的缓存器,因而使大流量实现了本地化。有多个共享的 CDN(例如 Akamai 和 Limelight)和专用的 CDN(例如谷歌和 Netflix)。

2.2.6 条件 GET 方法

尽管高速缓存能够减少用户感受到的响应时间,但也引入了一个新的问题,即存放在缓存器中的对象副本可能是陈旧的。

好在 HTTP 协议有一种机制,允许缓存器证实它的对象是最新的,即 条件 GET (conditional GET) 方法。

条件 GET :

  1. 请求报文使用 GET 方法;
  2. 请求报文包含一个”If-Modified-Since:“首部行。

例,一个代理缓存器(proxy cache)代表一个请求浏览器,向某个 Web 服务器发送一个请求报文:

该 Web 服务器向缓存器发送具有被请求的对象的响应报文:

该缓存器将对象转发到请求浏览器的同时,也在本地缓存了该对象。重要的是,缓存器在存储该对象时也存储了最后修改日期。一段时间后,另一个用户经过该缓存器请求同一个对象,该对象仍在该缓存器中,但是 Web 服务器中该对象可能被修改过了,该缓存器通过发送一个条件 GET 执行最新检查。该缓存器发送:

该条件 GET 报文告诉服务器,仅当自指定日期之后该对象被修改过,才发送该对象。

假设对象自 2015 年 9 月 9 日 09:23:24 后没有被修改,Web 服务器向该缓存器发送一个响应报文:

状态行中 304 Not Modified,告诉缓存器该对象没有被修改,可以向请求的浏览器转发该缓存器中缓存的对象。

2.3 因特网中的电子邮件

本节主要讨论位于因特网电子邮件的核心地位的应用层协议。首先从总体上看看因特网电子邮件系统和它的关键组件。

因特网电子邮件系统有 3 个主要组成部分: 用户代理(user agent)邮件服务器(mail server)简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)

Alice 发电子邮件给接收方 Bob 的场景如下:

  1. 用户代理:允许用户阅读、回复、转发、保存和撰写报文。

微软的 Outlook 和 Apple Mail 是电子邮件用户代理的例子。

  1. Alice 完成邮件撰写,它的邮件代理向其邮件服务器发送邮件,此时邮件放在邮件服务器的外出报文队列中。
  2. Bob 要阅读报文时,他的用户代理在其邮件服务器的邮箱中获得该报文。

邮件服务器形成了电子邮件体系结构的核心。每个接收方在其中的某个邮件服务器上有一个 邮箱(mailbox)

一个典型的邮件发送过程是: 从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后在这里被分发到接收方的邮箱中。当 Bob 要在它的邮箱中读取该报文时,包含他邮箱的邮件服务器(使用用户名和口令)来鉴别 Bob 。Alice 的邮箱也必须能处理 Bob 的邮箱服务器的故障。如果 Alice 的服务器不能将邮件交付给 Bob 的服务器, Alcie 的邮件服务器在一个 报文队列(message queue) 中保持该报文并在以后尝试再次发送。通常每 30 分钟左右进行一次尝试;如果几天后仍不能成功,服务器就删除该报文并以电子邮件的形式通知发送方。

SMTP 是因特网电子邮件中主要的应用层协议。它使用 TCP 可靠数据传输服务,从发送方的邮件服务器向接收方的邮件服务器发送邮件。

2.3.1 SMTP

SMTP 用于从发送方的邮件服务器发送报文到接收方的邮件服务器。但是它限制所有邮件报文的体部分(不只是其首部分)只能采用简单的 7 比特 ASCII 表示。

SMTP 的基本操作如下:

假设 Alice 想给 Bob 发送一封简单的 ASCII 报文:

  1. Alice 调用她的邮件代理程序并提供 Bob 的邮件地址(例如 [email protected]),撰写报文,然后指示用户代理发送该报文。
  2. Alice 的用户代理把报文发给她的邮件服务器,在那里该报文被放在报文队列中。
  3. 运行在 Alice 的邮件服务器上的 SMTP 客户端发现了报文队列中的这个报文,他就创建一个到运行在 Bob 邮件服务器上的 SMTP 服务器的 TCP 连接。
  4. 在经过一些初始 SMTP 握手后,SMTP 客户通过该 TCP 连接发送 Alice 的报文。
  5. 在 Bob 的邮件服务器上,SMTP 的服务器端接收该报文。Bob 的邮件服务器然后将该报文放入 Bob 的邮箱中。
  6. 在 Bob 方便的时候,他调用用户代理阅读该报文。、

SMTP 一般不使用中间邮件服务器发送邮件,这意味着邮件并不在中间的某个邮件服务器存留。

SMTP 用的是持续连接:如果发送邮件服务器有几个报文发往同一个接收邮件服务器,它可以通过同一个 TCP 连接发送这些所有的报文。

2.3.2 与 HTTP 的对比

相同点:

两个协议都用于从一台主机向另一个台主机传送文件:

  • HTTP 从 Web 服务器向 Web 客户(通常是一个浏览器)传送文件(也称为对象)
  • SMTP 从一个邮件服务器向另一个邮件服务器传送文件(即电子邮件报文)

在文件传输时,持续的 HTTP 和 SMTP 都使用持续连接。

不同点:

  1. HTTP 主要是一个 拉协议(pull protocol) ,某些人在 Web 服务器上装载信息,用户使用 HTTP 从该服务器拉取这些信息。特别是 TCP 连接由想接收文件的机器发起。

    SMTP 基本是一个 推协议(push protocol) ,即发送邮件服务器把文件推向接收邮件服务器。

  2. SMTP 要求每个报文用 7 比特 ASCII 码格式。如果发送的报文包含其他格式,需要按照 7 比特 ASCII 码进行编码。HTTP 不需要。

  3. 在处理一个既包含文本又包含图形(或其他媒体类型)的文档:

    HTTP 把每个对象封装到它自己的 HTTP 响应报文中;

    SMTP 把所有报文对象放在一个报文之中。

2.3.3 邮件报文格式

环境信息包含在一系列首部行中。首部行和该报文的体用空行(即回车换行)进行分隔。

每个首部必须包含有一个 From:首部行和一个 To:首部行;一个首部行也许包含 Subject:首部行以及其他可选的首部行。

一个典型的报文首部看起来如下:

在报文首部之后,紧接着一个空白行,然后是以 ASCII 格式表示的报文体。

2.3.4 邮件访问协议

典型的用户通常在本地 PC 上运行一个用户代理程序,而它访问存储在总是保持开机的共享邮件服务器上的邮箱。该邮件服务器与其他用户共享,并且通常由用户的 ISP 进行维护(如大学或公司)。

如下图, Bob 这样的接收方,是如何通过运行其本地 PC 上的用户代理,获得位于他的某 ISP 的邮件服务器上的邮件呢?

注意:Bob 的用户代理不能使用 SMTP 得到报文,因为取报文时一个拉操作,而 SMTP 协议是一个推协议。

通过引入一个特殊的邮件访问协议来解决这个难题,该协议将 Bob 邮件服务器上的报文传送给他的本地 PC。目前有一些流行的邮件访问协议,包括 第三版的邮局协议(Post Office Protocol—Version 3,POP3)因特网邮件访问协议(Internet Mail Access Protocol,IMAP) 以及 HTTP

1. POP3

POP3 是一个极为简单的邮件访问协议,它按照三个阶段进行工作:

  1. 特许(authorization):用户代理发送(以明文形式)用户名和口令鉴别用户。

    该阶段有两个主要的命令:user <user name>pass <password>

  2. 事务处理:用户代理取回报文(此阶段还可以对报文做删除标记,取消报文删除标记,以及获取邮件的统计信息)。

    使用 POP3 的用户代理通常被用户配置为”下载并删除“或者”下载并保留“方式。

    上图用户代理首先请求用剑服务器列出所有存储的报文的长度。接着用户代理从邮件服务器取回并删除每封邮件。

  3. 更新:出现在客户发出 quit 命令之后,目的是结束该 POP3 会话;这时,该邮件服务器删除那些被标记为删除的报文。

POP3 服务器并不在 POP3 会话过程中携带状态信息。会话中不包括状态信息大大简化了 POP3 服务的实现。

使用 POP3 访问时,一旦 Bob 将邮件下载到本地主机后,他就能建立邮件文件夹,并将下载的邮件放入该文件夹中。然后 Bob 可以删除报文,在文件夹之间移动报文,并查询报文(通过发送方的名字或报文主题)。但是这种文件夹和报文存放在本地主机上的方式,会给移动用户带来问题,因为用户更喜欢使用一个在远程服务器上的层次文件夹,这样它可以从任何一台机器上对所有报文进行访问。POP3 做不到,因为它没有给用户提供任何创建远程文件夹并为报文指派文件夹的方法。

2. IMAP

IMAP 协议为用户提供了创建文件夹以及将邮件从一个文件夹移动到另一个文件夹的命令。IMAP 还为用户提供了在远程文件夹中查询邮件的命令,按指定条件去查询匹配的邮件。IMAP 服务器维护了 IMAP 会话的用户信息,例如,文件夹的名字以及哪些报文与哪些文件夹相关联。

IMAP 的另一个重要特性是它具有允许用户代理获取报文某些部分的命令。例如,一个用户代理可以只读取一个报文的报文首部,或只是一个多部分 MIME 报文的一部分。当用户代理和其邮件服务器之间使用低带宽连接(如一个低速调制解调链路)的时候,这个特性非常有用。使用这种低带宽连接时,用户可能并不像取回他邮箱中的所有邮件,尤其要避免可能包含如音频或视频片段的大邮件。

3. 基于 Web 的电子邮件

今天越来越多的用户使用它们的 Web 浏览器收发电子邮件。

Alice 用户代理(HTTP)Alice 邮件服务器(SMTP)Bob 邮件服务器 (HTTP) Bob 用户代理

2.4 DNS :因特网的目录服务

主机的识别有两种方式:

  1. 主机名
  2. IP 地址

2.4.1 DNS 提供的服务

域名系统(Domain Name System,DNS) 的主要任务是能进行主机名到 IP 地址转换的目录服务。

DNS 是:

  1. 一个由分层的 DNS 服务器(DNS server) 实现的分布式数据库;
  2. 一个使得主机能够查询分布式数据库的应用层协议。

DNS 服务器通常是运行在 BIND(Berkeley Internet Name Domain)软件的 UNIX 机器。

DNS 协议运行在 UDP 之上,使用 53 号端口。

DNS 通常是由其他应用层协议所使用的,包括 HTTP、SMTP 和 FTP,将用户提供的主机名解析为 IP 地址。举一个例子,考虑运行在某用户主机上的一个浏览器(即一个 HTTP 客户)请求 URL www.someschool.edu/index.html 页面时,首先要获得 www.someschool.edu的 IP 地址:

  1. 同一台用户主机上运行着 DNS 应用的客户端。
  2. 浏览器从上述 URL 中抽取出主机名 www.someschool.edu ,并将这台主机名传给 DNS 应用的客户端。
  3. DNS 客户向 DNS 服务器发送一个包含主机名的请求。
  4. DNS 客户最终会收到一份回答报文,其中含有对应于该主机的 IP 地址。
  5. 一旦浏览器接收到来自 DNS 的该 IP 地址,它能够向位于该 IP 地址 80 端口的 HTTP 服务器进程发起一个 TCP 连接。

由上可知,DNS 给使用它的因特网应用带来了额外的时延。好在想获得的 IP 地址通常就缓存在一个”附近的“ DNS 服务器中,这有助于减少 DNS 的网络流量和 DNS 的平均时延。

除了进行主机名到 IP 地址的转换外, DNS 还提供了一些重要的服务:

  • 主机别名(host aliasing)。主机别名(当存在时)比主机规范名更加容易记忆。应用程序可以调用 DNS 来获得主机别名对应得规范主机名以及主机的 IP 地址。
  • 邮件服务器别名(mail server aliasing)。MX 记录允许一个公司的邮件服务器和 Web 服务器使用相同(别名化的)的主机名。
  • 负载分配(load distribution)。DNS 也用于在冗余的服务器之间进行负载分配。繁忙的站点(如 cnn.com)被冗余分布在多台服务器上,每台服务器均运行在不同的端系统上,每个都有着不同的 IP 地址。由于这些冗余的 Web 服务器,一个 IP 地址集合因此与同一个规范主机名相联系。DNS 数据库中存储着这些 IP 地址集合。当客户对映射到某地址集合的名字发出一个 DNS 请求时,该服务器用 IP 地址对整个集合进行响应,但在每个回答中循环这些地址次序。

2.4.2 DNS 工作机理概述

DNS 工作由分布于全球的大量 DNS 服务器以及定义了 DNS 服务器与查询主机通信方式的应用层协议组成。

集中式设计: 只是用一个 DNS 服务器,该服务器包含所有的映射。

集中式设计的问题:

  • 单点故障。如果该 DNS 服务器崩溃,整个因特网随之瘫痪。
  • 通信容量。单个 DNS 服务器不得不处理所有的 DNS 查询。
  • 远距离的集中式数据库。单个 DNS 服务器不可能”邻近“所有查询客户。如果用户和服务器距离很远将导致严重的时延。
  • 维护。单个 DNS 服务器将不得不为所有因特网主机保留记录,导致中央数据库庞大,而且还不得不为每个新添加的主机频繁更新。

单一的 DNS 服务器上运行集中式数据库完全没有可扩展能力。

分布式设计: DNS 是一个在因特网上实现分布式数据库的精彩案例。

1. 分布式、层次数据库

为处理扩展性问题,DNS 使用了大量的 DNS 服务器,它们以层次方式组织,并且分布在全世界范围内。没有一台 DNS 服务器拥有因特网上所有主机的映射。

大致有 3 中类型的 DNS 服务器:

  • 根 DNS 服务器。 根名字服务器提供 TLD 服务器的 IP 地址。

    有 400 多个根名字服务器遍及世界。

  • 顶级域(Top-Level Domain,TLD)DNS 服务器。 TLD 服务器提供了权威 DNS 服务器的 IP 地址。

    对每个顶级域名(如 com、org、net、edu 和 gov)和所有国家的顶级域名(如 uk、fr、ca 和 jp),都有 TLD 服务器(或服务器集群)。

  • 权威 DNS 服务器。 在因特网上具有公共可访问主机(如 Web 服务器和邮件服务器)的每个组织机构必须提供公共可访问的 DNS 记录,这些主机的名字映射为 IP 地址。

根、TLD 和权威 DNS 服务器都处在该 DNS 服务器的层次结构中。

另一类重要的 DNS 服务器,称为 本地 DNS 服务器(local DNS server) 。本地 DNS 服务器在上述三种服务器层次之外。每个 ISP (如一个居民区的 ISP 或一个机构的 ISP)都有一台本地 DNS 服务器(也叫默认名字服务器)。当主机与某个 ISP 连接时,该 ISP 提供一台主机的 IP 地址,该主机具有一台或多台其本地 DNS 服务器的 IP 地址(常常通过 DHCP)。通过访问 Windows 或 UNIX 的网络状态窗口,用户能够容易地确定他的本地 DNS 服务器地 IP 地址。主机与其本地 DNS 服务器通常“邻近”,访问时延更短。

迭代查询如下图:

实践中,查询通常遵循下图模式:从请求主机到本地 DNS 服务器地查询是递归的,其余查询是迭代的。

递归查询如下图:

2. DNS 缓存(DNS caching)

为了改善时延性能并减少在因特网上到处传输的 DNS 报文数量,DNS 广泛使用了缓存技术。

在一个请求链中,当某 DNS 服务器接收一个 DNS 回答(例如,包含某主机名到 IP 地址的映射)时,它能将映射缓存在本地存储器中。

由于主机和主机名与 IP 地址间的映射并不是永久的,DNS 服务器在一段时间后(通常设置为两天)将丢弃缓存信息。

因为有了缓存,该本地 DNS 服务器可以立即返回 cnn.com 的 IP 地址,而不必查询其他任何 DNS 服务器。

本地 DNS 服务器也能够缓存 TLD 服务器的 IP 地址,因而允许本地 DNS 绕过查询链中的根 DNS 服务器。事实上,因为缓存,除少数 DNS 查询外,根服务器都被绕过了。

2.4.3 DNS 记录和报文

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

资源记录时一个包含了下列字段的 4 元组:

(Name, Value, Type, TTL)

TTL 是该记录的生存时间,它决定了资源记录应当从缓存中删除的时间。

Name 和 Value 的值取决于 Type:

  • (主机名,主机名对应的 IP 地址, A)

    一条类型为 A 的资源记录提供了标准的主机名到 IP 地址的映射。例如,(relay1.bar.foo.com, 145.37.93.126, A)

  • (域, 获得该域中主机 IP 地址的权威 DNS 服务器的主机名, NS)

    这个记录用于沿着查找链来路由 DNS 查询。例如,(foo.com, dns.foo.com, NS)

  • (主机别名,Name 对应的规范主机名,CNAME)

    该记录能够向查询的主机提供一个主机名对应的规范主机名。例如,(foo.com, relay1.bar.foo.com, CNAME)

  • (邮件服务器别名,Name 对应的规范主机名, MX)

    获得邮件服务器的规范主机名。

    通过使用 MX 记录,一个公司的邮件服务器和其他服务器(如它的 Web 服务器)可以使用相同的别名。

DNS 报文:

内容略,图如下。

2.5 P2P 文件分发

在 P2P 文件分发中,每个对等方能够向任何其他对等方重新分发它已经收到的该文件的任何部分,从而在分发过程中协助服务器。

到 2016 年为止,最为流行的 P2P 文件分发协议是 BitTorrent。

1. P2P 体系结构的扩展性

usu_s 表示服务器介入链路的上载速率。

uiu_i 表示第 i 对等方接入链路的上载速率。

did_i 表示第 i 对等方接入链路的下载速率。

FF 表示被分发的文件长度(以比特计)。

NN 表示要获得的该文件副本的对等方的数量。

分发时间(distribution time) 是所有 N 个对等方得到该文件的副本所需要的时间。

客户—服务器体系结构分发时间:

DCSmax{NFus,Fdmin}D_{CS} \geq max\{\frac{NF}{u_s},\frac{F}{d_{min}}\}

P2P 分发时间:

DP2Pmax{Fus,Fdmin,NFus+i=1Nui}D_{P2P} \geq max\{\frac{F}{u_s},\frac{F}{d_{min}},\frac{NF}{u_s+\sum^{N}_{i=1}u_i}\}

由上图 P2P 体系结构的最小分发时间总是小于客户—服务器体系结构的分发时间,而且对于任意的对等方数量 N ,总是小于 1 小时,因此应用程序能够是自扩展的。这种扩展性的直接成因是:对等方除了是比特的消费者外还是它们的重新分发者。

2. BitTorrent

BitTorrent 是一种用于文件分发的流行 P2P 协议。用 BItTorrent 的术语来讲,参与一个特定文件分发的所有对等方的集合被称为一个洪流(torrent)。在一个洪流中的对等方彼此下载等长度的文件快(chunk),典型的块长度为 256KB。当一个对等方首次加入一个洪流时,它没有块。随着时间的流逝,它积累了越来越多的块。当它下载块时,也为其他对等方上传了多个块。一旦某对等方获得了整个文件(或仅具有块时),它可以(自私地)离开,或(大公无私地)留在该洪流中并继续向其他对等方上传块。

每个洪流具有一个基础设施节点,称为 追踪器(tracker) 。当一个对等方加入某洪流时,它向追踪器注册自己,并周期性的通知追踪器它仍在洪流中。

如下图,当一个新的对等方 Alice 加入该洪流时,追踪器随机地参与对等方地集合中选择对等方地集合中选择一个子集(设有 50 个对等方),并将这 50 个对等方地 IP 地址发送给 Alice。Alice 持有对等方地这张列表,试图与该列表上地所有对等方创建并行的 TCP 连接。所有与 Alice 成功创建一个 TCP 连接的对等方称为“邻近对等方”。随着时间的流逝,这些对等方中的某些可能离开,其他对等方(最初的 50 个之外的)可能试图与 Alice 创建 TCP 连接。因此一个对等方的邻近对等方将随时间而波动。

Alice 通过周期性的询问(经 TCP 连接)知道了邻近对等方所具有的块。

在决定请求哪些块的过程中,Alice 使用一种称为 最稀缺优先(rarest first)的技术 。这种技术的思路是,针对她没有的块在她的邻居中决定最稀缺的块(最稀缺的块就是那些在她的邻居中副本数量最少的块),并首先申请最稀缺的块。这样,最稀缺块得到更为迅速的重新分发,其目标是(大致)均衡每个块在洪流中的副本数量。

在决定响应哪个请求的过程中,BitTorrent 使用了一种机灵的对换算法。最基本想法是 Alice 根据当前最高速率向她提供数据的邻居,给出其优先权。特别是,Alice 对每个邻居都持续地测量接收到比特的速率,并确定以最高速率流入的 4 个邻居。每过 10s ,她重新计算该速率并可能修改这 4 个对等方的集合(这四个对等方被称为 **疏通(unchoked) ** )。每过 30s,她也要随机地选择另外一个邻居(Bob)并向其发送块。因为 Alice 正向 Bob 发送块,她可能成为 Bob 的 4 位上传者之一,这样的话 Bob 也开始向 Alice 发送数据。如果 Bob 向 Alice 发送数据的速率足够高,Bob 接下来也能称为 Alice 的前 4 位上传者。除了这 5个 对等方(前 4 个对等方和一个试探的对等方),其他所有相邻对等方均被“阻塞”,即它们不能从 Alice 接收到任何块。

2.6 视频流和内容分发网

很有趣,有关于 CDN 的知识,时间关系,以后有机会再看。

2.7 套接字编程:生成网络应用

典型的网络应用是由一对程序(即客户程序和服务器程序)组成的,它们位于两个不同的端系统中。当运行这两个程序时,创建了一个客户进程和一个服务器进程,同时它们通过从套接字读出和写入数据在彼此之间进行通信。开发者创建一个网络应用时,其主要任务就是编写客户端程序和服务器程序的代码。
网络应用程序有两类:

  1. 由协议标准(如一个 RFC 或某种其他标准文档)中所定义的操作实现;这样的应用程序有时称为“开放”的,因为定义其操作的这些规则为人们所公职。
  2. 专用的网络应用程序。在这种情况下,由客户和服务器程序应用的应用层协议没有公开发布,其他独立的开发者将不能开发出和该应用程序交互的代码。

2.7.1 UDP 套接字编程

当使用 UDP 时,必须先将目的地址附在该分组之上(该目的地址是由目的主机的 IP 地址和目的地套接字的端口号组成的)。

当生成套接字时,就为它分配一个称为 端口号(port number) 的标识符。

2.7.2 TCP 套接字编程

用户和服务器能够开始相互发送数据之前,他们先要握手和创建一个 TCP 连接。

使用创建的 TCP 连接,当一侧要向另一侧发送数据时,它只需要经过其套接字将数据丢进 TCP 连接。这与 UDP 不同,UDP 服务器在将分组丢京套接字之前必须为其附上一个目的地地址。

用户具有向服务器发起接触的任务,于是有以下两点要满足:

  1. 与 UDP 中的情况一样,TCP 服务器在用户访问之前要作为进程(serverSocket)运行起来。

  2. 用户起初接触的是 serverSocket 的 TCP 套接字对象,三次握手过程中创建一个连接套接字(connectionSocket)与用户完成握手,建立 TCP 连接。此后也是 connectionSocket 和用户进行通信。