计算机网络-02

 

第二章 应用层

网络应用是计算机网络存在的理由, 如果我们不能构想岀任何有用的应用, 也就没有任何必要去设计支持它们的网络协议了。

在本章中 , 我们学习有关网络应用的原理和实现方面的知识 。 我们从定义关键的应用层概念开始 , 其中包括应用程序所需要的网络服务、 客户和服务器、 进程和运输层接口。

2.1 应用层协议原理

应用层Application layer)是七层OSI模型的第七层。应用层直接和应用程序接口并提供常见的网络应用服务。应用层也向表示层发出请求。应用层是开放系统的最高层,是直接为应用进程提供服务的。【来源:百度百科

研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序 。例如 , 在 Web 应用程序中 , 有两个互相通信的不同的程序 : 一个是运行在用户主机 ( 平板电脑 、 智能电话等) 上的浏览器程序 ; 另一个是运行在 Web 服务器主机上的 Web 服务器程序 。 在这种情况下 , 在各台主机中的这些程序可能都是类似的或相同的 。 因此 , 当研发新应用程序时 , 你需要编写将在多台端系统上运行的软件。 该软件能够用如 C 、 Java 或 Python 来编写。 重要的是 , 你不需要写在网络核心设备如路由器或链路层交换机上运行的软件。即使你要为网络核心设备写应用程序软件 , 你也不能做到这一点 。 网络核心设备并不在应用层上起作用,而仅在较低层起作用,特别是在网络层及下面层次起作用 。 这种基本设计, 即将应用软件限制在端系统( 如图 2 -1 所示)的方法 , 促进了大量的网络应用程序的迅速研发和部署 。研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序 。

2022-05-01 12-37-49 的屏幕截图

2.1.1 网络应用程序体系结构

从应用程序研发者的角度看,网络体系结构是固定的, 并为应用程序提供了特定的服务集合。 在另一方面, 应用程序体系结构 ( application architecture ) 由应用程序研发者设计,规定了如何在各种端系统上组织该应用程序 。 在选择应用程序体系结构时 , 应用程序研发者很可能利用现代网络应用程序中所使用的两种主流体系结构之一 :客户-服务器体系结构对等 ( P2P) 体系结构

客户-服务器体系结构 ( client-server architecture ) 中 , 有一个总是打开的主机称为服务器 , 它服务于来自许多其他称为客户的主机的请求 。一个典型的例子是 Web 应用程序 , 其中总是打开的 Web 服务器服务于来自浏览器 (运行在客户主机上 )的请求 。 当Web 服务器接收到来自某客户对某对象的请求时 , 它向该客户发送所请求的对象作为响应 。值得注意的是利用客户-服务器体系结构 , 客户相互之间不直接通信 ; 例如 , 在 Web应用中两个浏览器并不直接通信。 客户-服务器体系结构的另一个特征是该服务器具有固定的 、周知的地址 ,该地址称为 IP 地址 。 因为该服务器具有固定的 、周知的地址 , 并且因为该服务器总是打开的, 客户总是能够通过向该服务器的 IP 地址发送分组来与其联系 。具有客户-服务器体系结构的非常著名的用程序包括 Web 、FTP 、 Telnet 和电子邮件。 图 2-2a 中显示了这种客户-服务器体系结构 。

在一个客户-服务器应用中 , 常常会出现一台单独的服务器主机跟不上它所有客户请求的情况。例如 , 一个流行的社交网络站点如果仅有一台服务器来处理所有请求 , 将很快变得不堪重负 。为此 ,配备大量主机的数据中心 (data center)常被用于创建强大的虚拟服务器。 最为流行的因特网服务一 一 如搜索引擎 ( 如谷歌 、 Bing 和百度 ) 、 因特网商务( 如亚马逊 、 e-Bay 和阿里巴巴 ) 、 基于 Web 的电子邮件 ( 如 Gmail 和雅虎邮件 ) 、 社交网络( 如脸书、 Instagram 推特和微信 ), 就应用了一个或多个数据中心 。 如在 1.3.3 节中所讨论的那样 ,谷歌有分布于全世界的 30 〜 50 个数据中心 ,这些数据中心共同处理搜索 、YouTube 、 Gmail 和其他服务。一个数据中心能够有数十万台服务器 , 它们必须要供电和维护 。 此外 , 服务提供商必须支付不断出现的互联和带宽费用, 以发送和接收到达 / 来自数据中心的数据 。

2022-05-01 12-44-59 的屏幕截图

在一个 P2P 体系结构 ( P2P architecture) 中 , 对位于数据中心的专用服务器有最小的( 或者没有 ) 依赖 。 相反 , 应用程序在间断连接的主机对之间使用直接通信 ,这些主机对被称为对等方 。这些对等方并不为服务提供商所有 ,相反却为用户控制的设备所有 , 大多数对等方驻留在家庭 、 大学和办公室 。 因为这种对等方通信不必通过专门的服务器 ,该体系结构被称为对等方到对等方的 。 许多目前流行的 、 流量密集型应用都是 P2P体系结构的 。 这些应用包括文件共享 ( 例如 BitTorrent) 、 对等方协助下载加速器 ( 例如迅雷) 、 因特网电话和视频会议( 例如 Skype) 。 图 2- 2b 中显示了 P2P 的体系结构 。 需要提及的是 , 某些应用具有混合的体系结构 , 它结合了客户-服务器和 P2P 的元素 。例如 , 对于许多即时讯息应用而言, 服务器被用于跟踪用户的 IP 地址 , 但用户到用户的报文在用户主机之间( 无须通过中间服务器 )直接发送 。

P2P 体系结构的最引人入胜的特性之一是它们的自扩展性 ( self-scalability )。例如,在一个 P2P 文件共享应用中 , 尽管每个对等方都由于请求文件产生工作负载, 但每个对等方通过向其他对等方分发文件也为系统增加服务能力。 P2P 体系结构也是有成本效率的,因为它们通常不需要庞大的服务器基础设施和服务器带宽 (这与具有数据中心的客户-服务器设计形成鲜明对比 ) 。 然而, 未来 P2P 应用由于高度非集中式结构 ,面临安全性 、 性能和可靠性等挑战 。

2.1.2 进程通信

在构建网络应用程序前 ,还需要对运行在多个端系统上的程序是如何互相通信的情况有一个基本了解 。 用操作系统的术语来说,进行通信的实际上是进程 ( process) 而不是程序 。一个进程可以被认为是运行在端系统中的一个程序 。 当多个进程运行在相同的端系统上时 , 它们使用进程间通信机制相互通信。 进程间通信的规则由端系统上的操作系统确定 。 而在本书中 , 我们并不特别关注同一台主机上的进程间的通信 ,而关注运行在不同端系统( 可能具有不同的操作系统) 上的进程间的通信。在两个不同端系统上的进程,通过跨越计算机网络交换报文 ( message) 而相互通信。发送进程生成并向网络中发送报文 ; 接收进程接收这些报文并可能通过回送报文进行响应 。 图 2 -1 显示了驻留在 5 层协议栈的应用层进程互相通信的情况。

  • 客户和服务器进程

    网络应用程序由成对的进程组成 ,这些进程通过网络相互发送报文 。对每对通信进程,我们通常将这两个进程之一标识为客户 ( client), 而另一个进程标识为服务器 ( server)。对于 Web 而言, 浏览器是一个客户进程, Web 服务器是一台服务器进程 。 对于 P2P 文件共享 , 下载文件的对等方标识为客户 , 上载文件的对等方标识为服务器。

    我们定义客户和服务器进程如下 : 在一对进程之间的通信会话场景中 , 发起通信 ( 即在该会话开始时发起与其他进程的联系)的进程被标识为客户 , 在会话开始时等待联系的进程是服务器。

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

    进程通过一个称为套接字 ( socket) 的软件接口向网络发送报文和从网络接收报文 。 我们考虑一个类比来帮助我们理解进程和套接字 。 进程可类比于一座房子 ,而它的套接字可以类比于它的门 。 当一个进程想向 位于另外一台主机上的另一个进程发送报文时 , 它把报文推出该门( 套接字 ) 。 该发送进程假定该门到另外一侧之间有运输的基础设施 ,该设施将把报文传送到目的进程的门口。一旦该报文抵达目的主机 , 它通过接收进程的门( 套接字 ) 传递, 然后接收进程对该报文进行处理 。

    如图2-3所示,套接字是同一台主机内应用层与运输层之间的接口。 由于该套接字是建立网络应用程序的可编程接口 , 因此套接字也称为应用程序和网络之间的应用程序编程接口 ( Application Programming Interface, API)。应用程序开发者可以控制套接字在应用层端的一切 , 但是对该套接字的运输层端几乎没有控制权 。 应用程序开发者对于运输层的控制仅限于 : ①选择运输层协议; ②也许能设定几个运输层参数 , 如最大缓存和最大报文段长度等( 将在第 3 章中涉及 )。

2022-05-01 13-04-12 的屏幕截图

  • 进程寻址

    为了向特定目的地发送邮政邮件 ,目的地需要有一个地址 。 类似地 , 在一台主机上运行的进程为了向在另一台主机上运行的进程发送分组, 接收进程需要有一个地址 。为了标识该接收进程,需要定义两种信息 : ①主机的地址 ; ②在目的主机中指定接收进程的标识符 。

    在因特网中 , 主机由其 IP 地址 ( IP address ) 标识 。 我们将在第 4 章中非常详细地讨论 IP 地址 。 此时 , 我们只要知道 IP 地址是一个 32 比特的量且它能够唯一地标识该主机就够了。 除了知道报文发送目的地的主机地址外 , 发送进程还必须指定运行在接收主机上的接收进程(更具体地说, 接收套接字)。 因为一般而言一台主机能够运行许多网络应用,这些信息是需要的 。 目的地端口号 (port number) 用于这个目的 。 已经给流行的应用分配了特定的端口号。例如 , Web 服务器用端口号 80 来标识 。 邮件服务器进程(使用 SMTP协议)用端口号 25 来标识 。 用于所有因特网标准协议的周知端口号的列表能够在 http://www.iana.org处找到。 我们将在第 3 章中详细学习端口号。

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

包括因特网在内的很多网络提供了不止一种运输层协议 。 当开发一个应用时 , 必须选择一种可用的运输层协议 。 如何做出这种选择呢 ? 最可能的方式是 ,通过研究这些可用的运输层协议所提供的服务 ,选择一个最能为你的应用需求提供恰当服务的协议 。 这种情况类似于在两个城市间旅行时选择飞机还是火车作为交通工具。 每种运输模式为你提供不同的服务 , 你必须选择一种或另一种(例如 , 火车可以直到市区上客和下客 ,而飞机提供了 更短的旅行时间)。 一个运输层协议能够为调用它的应用程序提供什么样的服务呢 ? 我们大体能够从四个方面对应用程序服务要求进行分类: 可靠数据传输 、吞吐量 、 定时和安全性

  • 可靠数据传输

    如第 1 章讨论的那样 , 分组在计算机网络中可能丢失 。例如 , 分组能够使路由器中的缓存溢岀 , 或者当分组中的某些比特损坏后可能被丢弃 。像电子邮件、 文件传输 、 远程主机访问 、 Web 文档传输以及金融应用等这样的应用, 数据丢失可能会造成灾难性的后果 (在后一种情况下 , 无论对银行或对顾客都是如此 ! )。 因此 , 为了支持这些应用, 必须做一些工作以确保由应用程序的一端发送的数据正确 、 完全地交付给该应用程序的另一端 。如果一个协议提供了这样的确保数据交付服务 , 就认为提供了可靠数据传输 ( reliable data transfer)。 运输层协议能够潜在地向应用程序提供的一个重要服务是进程到进程的可靠数据传输 。 当一个运输协议提供这种服务时 , 发送进程只要将其数据传递进套接字 , 就可以完全相信该数据将能无差错地到达接收进程 。 当一个运输层协议不提供可靠数据传输时 ,由发送进程发送的某些数据可能到达不了接收进程 。 这可能能被容忍丢失的应用 ( loss-tolerant application ) 所接受 , 最值得注意的是多媒体应用, 如交谈式音频 / 视频, 它们能够承受一定量的数据丢失 。 在这些多媒体应用中 , 丢失的数据引起播放的音频 / 视频出现小干扰 ,而不是致命的损伤。

  • 吞吐量

    具有吞吐量要求的应用程序被称为带宽敏感的应用 ( bandwidth-sensitive application) 。带宽敏感的应用具有特定的吞吐量要求 ,而弹性应用( elastic application ) 能够根据当时可用的带宽或多或少地利用可供使用的吞吐量 。

  • 定时

    运输层协议也能提供定时保证 。 如同具有吞吐量保证那样 , 定时保证能够以多种形式实现 。一个保证的例子如 : 发送方注入进套接字中的每个比特到达接收方的套接字不迟于100ms 。对于非实时的应用,较低的时延总比较高的时延好 , 但对端到端的时延没有严格的约束 。

  • 安全性

    最后 ,运输协议能够为应用程序提供一种或多种安全性服务。例如 , 在发送主机中 ,运输协议能够加密由发送进程传输的所有数据 , 在接收主机中 ,运输层协议能够在将数据交付给接收进程之前解密这些数据。

2.1.4 因特网提供的运输服务

因特网( 更一般的是 TCP/IP 网络) 为应用程序提供两个运输层协议, 即 UDP 和 TCP 。 当为因特网创建一个新的应用时 ,首先要做出的决定是 ,选择 UDP 还是选择 TCP 。 每个协议为调用它们的应用程序提供了不同的服务集合。 图 2-4 显示了某些所选的应用程序的服务要求 。

2022-05-01 13-19-12 的屏幕截图

  • TCP 服务

    TCP 服务模型包括面向连接服务和可靠数据传输服务。 当某个应用程序调用 TCP 作为其运输协议时 ,该应用程序就能获得来自 TCP 的这两种服务。

    TCP 协议还具有拥塞控制机制 ,这种服务不一定能为通信进程带来直接好处 , 但能为因特网带来整体好处 。 当发送方和接收方之间的网络出现拥塞时 , TCP 的拥塞控制机制会抑制发送进程( 客户或服务器 ) 。

    • 面向连接的服务 : 在应用层数据报文开始流动之前 ,TCP 让客户和服务器互相交换运输层控制信息 。这个所谓的握手过程提醒客户和服务器 ,让它们为大量分组的到来做好准备 。在握手阶段后, 一个 TCP 连接 ( TCP connection )就在两个进程的套接字之间建立了。这条连接是全双工的, 即连接双方的进程可以在此连接上同时进行报文收发。当应用程序结束报文发送时 ,必须拆除该连接 。
    • 可靠的数据传送服务 :通信进程能够依靠 TCP, 无差错 、 按适当顺序交付所有发送的数据 。 当应用程序的一端将字节流传进套接字时 , 它能够依靠 TCP 将相同的字节流交付给接收方的套接字 ,而没有字节的丢失和冗余。
  • UDP 服务

    UDP 是一种不提供不必要服务的轻量级运输协议, 它仅提供最小服务。 UDP 是无连接的, 因此在两个进程通信前没有握手过程 。 UDP 协议提供一种不可靠数据传送服务 , 也就是说, 当进程将一个报文发送进 UDP 套接字时 , UDP 协议并不保证该报文将到达接收进程 。不仅如此 , 到达接收进程的报文也可能是乱序到达的 。

    UDP 没有包括拥塞控制机制 , 所以 UDP 的发送端可以用它选定的任何速率向其下层(网络层 ) 注入数据 。 ( 然而, 值得注意的是实际端到端吞吐量可能小于该速率,这可能是因为中间链路的带宽受限或因为拥塞而造成的 。 )

  • 因特网运输协议所不提供的服务

    在我们对 TCP 和 UDP 的简要描述中 , 明显地漏掉了对吞吐量或定时保证的讨论, 即这些服务目前的因特网运输协议并没有提供。 这是否意味着诸如因特网电话这样的时间敏感应用不能运行在今天的因特网上呢 ?答案显然是否定的, 因为在因特网上运行时间敏感应用已经有多年了。 这些应用经常工作得相当好 , 因为它们已经被设计成尽最大可能对付这种保证的缺乏。 我们将在第 9 章中研究几种设计技巧 。 无论如何 , 在时延过大或端到端吞吐量受限时 , 好的设计也是有限制的 。 总之 , 今天的因特网通常能够为时间敏感应用提供满意的服务 , 但它不能提供任何定时或带宽保证 。图 2-5 指出了一些流行的因特网应用所使用的运输协议 。

2022-05-01 13-29-26 的屏幕截图

2.1.5 应用层协议

我们刚刚学习了通过把报文发送进套接字实现网络进程间的相互通信。但是如何构造这些报文 ? 在这些报文中的各个字段的含义是什么 ?进程何时发送这些报文 ?这些问题将我们带进应用层协议的范围 。 应用层协议( application-layer protocol ) 定义了运行在不同端系统上的应用程序进程如何相互传递报文 。 特别是应用层协议定义了 :

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

2.2 Web和HTTP

20 世纪 90 年代以前 , 因特网的主要使用者还是研究人员、 学者和大学生, 他们登录远程主机 , 在本地主机和远程主机之间传输文件 , 收发新闻, 收发电子邮件。 尽管这些应用非常有用( 并且继续如此 ), 但是因特网基本上不为学术界和研究界之外所知 。到了 20 世纪 90 年代初期 , 一个主要的新型应用即万维网 ( World Wide Web) 登上了舞台。 Web 是一个引起公众注意的因特网应用, 它极大地改变了人们与工作环境内外交流的方式 。 它将因特网从只是很多数据网之一的地位提升为仅有的一个数据网 。

也许对大多数用户来说, 最具有吸引力的就是 Web 的按需操作。 当用户需要时 , 就能得到所想要的内容 。 这不同于无线电广播和电视, 它们迫使用户只能收听、 收看内容提供者提供的节目 。 除了可以按需操作以外 , Web 还有很多让人们喜欢和珍爱的特性 。任何人使信息在 Web 上可用都非常简单 , 即只需要极低的费用就能成为出版人。 超链接和搜索引擎帮助我们在 Web 站点的海洋里导航 。 图片和视频刺激着我们的感官 。 表单、 JavaScript. Java 小程序和很多其他的装置, 使我们可以与 Web 页面和站点进行交互。 并且 , Web 及其协议作为平台 , 为 YouTube , 基于 Web 的电子邮件 ( 如 Gmail ) 和大多数移动因特网应用( 包括 Instagram 和谷歌地图 ) 服务。

2.2.1 HTTP概况

Web 的应用层协议是超文本传输协议( HyperText Transfer Protocol , HTTP), 它是 Web的核心 , 在 RFC中进行了定义。 HTTP 由两个程序实现: 一个客户程序和一个服务器程序 。 客户程序和服务器程序运行在不同的端系统中 ,通过交换HTTP 报文进行会话 。 HTTP 定义了这些报文的结构以及客户和服务器进行报文交换的方式 。 在详细解释 HTTP 之前 , 应当回顾某些 Web 术语 。

  • Web 页面 ( Web page) ( 也叫文档 ) 是由对象组成的 。
  • 一个对象 ( object) 只是一个文件 ,诸如一个 HTML 文件、一个 JPEG 图形 、一个 Java 小程序或一个视频片段这样的文件,且它们可通过一个 URL 地址寻址 。
  • 多数 Web 页面含有一个 HTML 基本文件 ( base HTML file) 以及几个引用对象 。例如 , 如果一个 Web 页面包含 HTML 文本和 5 个 JPEG 图形 ,那么这个 Web 页面有 6 个对象: 一个 HTML 基本文件加 5 个图形 。
  • 因为 Web 浏览器 ( Web browser) ( 例如 Internet Explorer 和 Firefox) 实现 了 HTTP 的客 户端, 所以在 Web 环境中我们经常交替使用 “ 浏览器”和“ 客户 ” 这两个术语 。
  • Web 服务器 ( Web server) 实现了 HTTP 的服务器端, 它用于存储 Web 对象, 每个对象由 URL 寻 址 。

HTTP 定义了 Web 客户向 Web 服务器请求 Web 页面的方式 , 以及服务器向客户传送 Web 页面的方式 。 其基本思想在图2-6 中进行了图示 。 当用户请求一个 Web 页面 (如点击一个超链接)时 , 浏览器向服务器发出对该页面中所包含对象的运行 Apache Web服务器的服务器HTTP 请求报文 , 服务器接收到请求并用包含这些对象的 HTTP 响应报文进行响应 。

2022-05-01 13-44-36 的屏幕截图

HTTP 使用 TCP 作为它的支撑运输协议(而不是在 UDP 上运行)。 HTTP 客户首先发起一个与服务器的 TCP 连接 。一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问 TCP 。

注意到下列现象很重要: 服务器向客户发送被请求的文件 ,而不存储任何关于该客户的状态信息 。假如某个特定的客户在短短的几秒内两次请求同一个对象, 服务器并不会因为刚刚为该客户提供了该对象就不再做出反应 ,而是重新发送该对象, 就像服务器已经完全忘记不久之前所做过的事一样 。 因为 HTTP 服务器并不保存关于客户的任何信息 ,所以我们说 HTTP 是一个无状态协议 ( stateless protocol ) 。我们同时也注意到 Web 使用了客户-服务器应用程序体系结构。 Web 服务器总是打开的, 具有一个固定的IP 地址 , 且它服务于可能来自数以百万计的不同浏览器的请求 。

2.2.2 非持续连接和持续连接

在许多因特网应用程序中 , 客户和服务器在一个相当长的时间范围内通信 , 其中客户发出一系列请求并且服务器对每个请求进行响应 。依据应用程序以及该应用程序的使用方式 ,这一系列请求可以以规则的间隔周期性地或者间断性地一个接一个发出。 当这种客户-服务器的交互是经 TCP 进行的, 应用程序的研制者就需要做一个重要决定 , 即每个请求 /响应对是经一个单独的 TCP 连接发送,还是所有的请求及其响应经相同的 TCP 连接发送呢 ?采用前一种方法 ,该应用程序被称为使用非持续连接 ( non-persistent connection ) ;采用后一种方法 ,该应用程序被称为使用持续连接 ( persistent connection )

  • 采用非持续连接的 http

    我们看看在非持续连接情况下 , 从服务器向客户传送一个 Web 页面的步骤 。假设该页面含有一个 HTML 基本文件和 10 个 JPEG 图形 , 并且这 11 个对象位于同一台服务器上。 进一步假设该 HTML 文件的 URL 为 : http://www.someSchool.edu/someDepartment/home.index 。

    我们看看发生了什么情况 :

    1 ) HTTP 客户进程在端口号 80 发起一个到服务器的 TCP 连接 ,该端口号是 HTTP 的默认端口。 在客户和服务器上分别有一个套接字与该连接相关联 。

    2 ) HTTP 客户经它的套接字向该服务器发送一个 HTTP 请求报文 。 请求报文中包含了路径名 /someDepartment/home. index 。

    3 ) HTTP 服务器进程经它的套接字接收该请求报文 , 从其存储器 ( RAM 或磁盘) 中检索出对象 www.someSchool.edu/someDepartment/home. index, 在一个 HTTP 响应报文中封装对象, 并通过其套接字向客户发送响应报文 。

    4 ) HTTP 服务器进程通知 TCP 断开该 TCP 连接 。 ( 但是直到 TCP 确认客户已经完整地收到响应报文为止 , 它才会实际中断连接 。 )

    5 ) HTTP 客户接收响应报文 , TCP 连接关闭 。 该报文指岀封装的对象是一个 HTML 文件 , 客户从响应报文中提取出该文件 , 检査该 HTML 文件 , 得到对 10 个 JPEG 图形的引用 。

    6 ) 对每个引用的 JPEG 图形对象重复前 4 个步骤 。

    上面的步骤举例说明了非持续连接的使用, 其中每个 TCP 连接在服务器发送一个对象后关闭, 即该连接并不为其他的对象而持续下来 。值得注意的是每个 TCP 连接只传输一个请求报文和一个响应报文 。 因此在本例中 , 当用户请求该 Web 页面时 ,要产生 11 个 TCP 连接 。

    在继续讨论之前 , 我们来简单估算一下从客户请求 HTML 基本文件起到该客户收到整个文件止所花费的时间 。为此 , 我们给出往返时间RTT ( Round-Trip Time, RTT) 的定义 ,该时间是指一个短分组从客户到服务器然后再返回客户所花费的时间 。 RTT 包括分组传播时延 、分组在中间路由器和交换机上的排队时延以及分组处理时延 。

    现在考虑当用户点击超链接时会发生什么现象 。如图 2-7 所示,这引起浏览器在它和 Web 服务器之间发起一个 TCP 连接 ;这涉及一次 “三次握手 ” 过程,即客户向服务器发送一个小 TCP 报文段 , 服务器用一个小 TCP 报文段做出确认和响应,最后 , 客户向服务器返回确认 。三次握手中前两个部分所耗费的时间占用了一个 RTT 。 完成了三次握手的前两个部分后 , 客户结合三次握手的第三部分 (确认) 向该 TCP 连接发送一个 HTTP 请求报文 。一旦该请求报文到达服务器 , 服务器就在该 TCP 连接上发送HTML 文件。 该 HTTP 请求/响应用去了另一个 RTT 。 因此 ,粗略地讲, 总的响应时间就是两个 RTT 加上服务器传输 HTML 文件的时间 。

2022-05-01 14-10-06 的屏幕截图

  • 采用持续连接的 HTTP

    非持续连接有一些缺点 。 第一 , 必须为每一个请求的对象建立和维护一个全新的连接 。 对于每个这样的连接 , 在客户和服务器中都要分配 TCP 的缓冲区和保持 TCP 变量,这给 Web 服务器带来了严重的负担 , 因为一台 Web 服务器可能同时服务于数以百计不同的客户的请求 。 第二 , 就像我们刚描述的那样 , 每一个对象经受两倍 RTT 的交付时延,即一个 RTT 用于创建 TCP, 另一个 RTT 用于请求和接收一个对象 。

    在采用 HTTP 1.1 持续连接的情况下 , 服务器在发送响应后保持该 TCP 连接打开 。 在相同的客户与服务器之间, 后续的请求和响应报文能够通过相同的连接进行传送 。 特别是 , 一个完整的 Web 页面( 上例中的 HTML 基本文件加上 10 个图形 ) 可以用单个持续TCP 连接进行传送 。 更有甚者, 位于同一台服务器的多个 Web 页面在从该服务器发送给同一个客户时 , 可以在单个持续 TCP 连接上进行 。 对对象的这些请求可以一个接一个地发出 ,而不必等待对未决请求 ( 流水线)的回答 。一般来说, 如果一条连接经过一定时间间隔( 一个可配置的超时间隔) 仍未被使用, HTTP 服务器就关闭该连接 。 HTTP 的默认模式是使用带流水线的持续连接 。

2.2.3 HTTP 报文格式

见书P67。

我们前面提到了 HTTP 服务器是无状态的 。 这简化了服务器的设计, 并且允许工程师们去开发可以同时处理数以千计的 TCP 连接的高性能 Web 服务器。 然而一个 Web 站点通常希望能够识别用户 , 可能是因为服务器希望限制用户的访问, 或者因为它希望把内容与用户身份联系起来 。为此 , HTTP 使用了 cookie 。 cookie 在 [ RFC 6265 ] 中定义 , 它允许站点对用户进行跟踪 。 目前大多数商务 Web 站点都使用了 cookie。

2022-05-01 14-14-55 的屏幕截图

如图 2-10 所示, cookie 技术有 4 个组件 :

①在 HTTP 响应报文中的一个 cookie 首部行;

②在 HTTP 请求报文中的一个 cookie首部行;

③在用户端系统中保留有一个 cookie 文件 , 并由用户的浏览器进行管理;

④位于 Web 站点的一个后端数据库 。

使用图 2-10, 我们通过一个典型的例子看看 cookie 的工作过程 。假设 Susan 总是从家中 PC 使用 Internet Explorer 网, 她首次与 Amazon, com 联系 。 我们假定过去她已经访问过 eBay 站点 。 当请求报文到达该 Amazon Web 服务器时 ,该 Web 站点将产生一个唯一识别码, 并以此作为索引在它的后端数据库中产生一个表项 。 接下来 Amazon Web 服务器用一个包含 Set-cookie :首部的 HTTP 响应报文对 Susan 的浏览器进行响应 , 其中 Set-cookie : 首部含有该识别码 。 例如 ,该首部行可能是:

Set-cookie :1678

当 Susan 的浏览器收到了该 HTTP 响应报文时 , 它会看到该 Set-cookie : 首部 。 该浏览器在它管理的特定 cookie 文件中添加一行,该行包含服务器的主机名和在 Set-cookie : 首部中的识别码 。值得注意的是该 cookie 文件已经有了用于 eBay 的表项, 因为 Susan 过去访问过该站点 。 当 Susan 继续浏览 Amazon 网站时 , 每请求一个 Web 页面, 其浏览器就会查询该cookie 文件并抽取她对这个网站的识别码, 并放到 HTTP 请求报文中包括识别码的 cookie 首部行中。 特别是 , 发往该 Amazon 服务器的每个 HTTP 请求报文都包括以下首部行:

Cookie :1678

在这种方式下 , Amazon 服务器可以跟踪 Susan 在 Amazon 站点的活动。 尽管 Amazon Web 站点不必知道 Susan 的名字 , 但它确切地知道用户 1678 按照什么顺序 、 在什么时间 、访问了哪些页面! Amazon 使用 cookie 来提供它的购物车服务 , 即 Amazon 能够维护 Susan希望购买的物品列表,这样在 Susan 结束会话时可以一起为它们付费 。

如果 Susan 再次访问 Amazon 站点 , 比如说一个星期后 , 她的浏览器会在其请求报文中继续放入首部行 cookie : 1678。 Amazon 将根据 Susan 过去在 Amazon 访问的网页向她推荐产品。 如果 Susan 也在 Amazon 注册过, 即提供了她的全名、 电子邮件地址 、 邮政地址和信用卡账号 , 则 Amazon 能在其数据库中包括这些信息 , 将 Susan 的名字与识别码相关联( 以及她在过去访问过的本站点的所有页面) 。 这就解释了 Amazon 和其他一些电子商务网站实现”点击购物( one-click shopping ) 的道理, 即当 Susan 在后继的访问中选择购买某个物品时 , 她不必重新输入姓名、信用卡账号或者地址等信息了。

从上述讨论中我们看到 , cookie 可以用于标识一个用户 。 用户首次访问一个站点时 , 可能需要提供一个用户标识( 可能是名字 ) 。 在后继会话中 , 浏览器向服务器传递一个 cookie首部, 从而向该服务器标识了用户 。 因此 cookie 可以在无状态的 HTTP 之上建立一个用户会话层 。例如 , 当用户向一个基于 Web 的电子邮件系统( 如 Hot mail) 注册时 , 浏览器向服务器发送 cookie 信息 , 允许该服务器在用户与应用程序会话的过程中标识该用户 。

2.2.5 Web 缓存

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

2022-05-01 14-26-28 的屏幕截图

举例来说, 假设浏览器正在请 求对象 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 购买并安装 。例如 , 一所大学可能在它的校园网上安装一台缓存器 , 并且将所有校园网上的用户浏览器配置为指向它 。 或者, 一个主要的住宅 ISP ( 例如 Comcast ) 可能在它的网络上安装一台或多台 Web 缓存器 , 并且预先配置其配套的浏览器指向这些缓存器。

在因特网上部署 Web 缓存器有两个原因 。 首先 , Web 缓存器可以大大减少对客户请求的响应时间,特别是当客户与初始服务器之间的瓶颈带宽远低于客户与 Web 缓存器之间的瓶颈带宽时更是如此 。 如果在客户与 Web 缓存器之间有一个高速连接 ( 情况常常如此 ), 并且如果用户所请求的对象在 Web 缓存器上 , 则 Web 缓存器可以迅速将该对象交付给用户 。其次 , 如我们马上用例子说明的那样 , Web 缓存器能够大大减少一个机构的接入链路到因特网的通信量。 通过减少通信量,该机构 ( 如一家公司或者一所大学 ) 就不必急于增加带宽 , 因此降低了费用 。

2.2.6 条件GET方法

详情请阅读书籍P74。

2.3 因特网中的电子邮件

详情请阅读书籍P93。

2.4 DNS : 因特网的目录服务

人类能以很多方式来标识 。例如 , 我们能够通过出生证书上的名字来标识;能够通过社会保险号码来标识; 也能够通过驾驶执照上的号码来标识 。

因特网上的主机和人类一样 , 可以使用多种方式进行标识 。主机的一种标识方法是用它的主机名 ( hostname ) ,如www.baidu.com 、 www.google.com 等。 然而, 主机名几乎没有提供( 即使有也很少 ) 关于主机在因特网中位置的信息 。 ( 一个名为 www. eurecom. fr 的主机以国家码 .fr 结束 , 告诉我们该主机很可能在法国,仅此而已 。 ) 况且 , 因为主机名可能由不定长的字母数字组成 ,路由器难以处理 。 由于这些原因 , 主机也可以使用所谓 IP 地址( IP address) 进行标识 。

2.4.1 DNS 提供的服务

我们刚刚看到了识别主机有两种方式 ,通过主机名或者 IP 地址 。人们喜欢便于记忆的主机名标识方式 ,而路由器则喜欢定长的 、 有着层次结构的 IP 地址 。为了折中这些不同的偏好 , 我们需要一种能进行主机名到 IP 地址转换的目录服务。 这就是域名系统( Domain Name System , DNS) 的主要任务。

DNS 是 : ①一个由分层的 DNS 服务器 ( DNS server) 实现的分布式数据库 ; ②一个使得主机能够查询分布式数据库的应用层协议 。DNS 服务器通常是运行 BIND ( Berkeley Internet Name Domain) 软件 [BIND 2012 ] 的UNIX 机器。 DNS 协议运行在 UDP 之上 , 使用 53 号端口。

DNS 通常是由其他应用层协议所使用的, 包括 HTTP 、 SMTP 和 FTP, 将用户提供的主机名解析为 IP 地址

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

  • 主机别名 (host aliasing):有着复杂主机名的主机能拥有一个或者多个别名。
  • 邮件服务器别名 ( mail server aliasing):电子邮件应用程序可以调用 DNS, 对提供的主机名别名进行解析 , 以获得该主机的规范主机名及其 IP 地址 。
  • 负载分配 (load distribution):
  • DNS 也用于在冗余的服务器 ( 如冗余的 Web 服务器等) 之间进行负载分配 。 繁忙的站点 ( 如 cnn. com )被冗余分布在多台服务器上,每台服务器均运行在不同的端系统上 , 每个都有着不同的 IP 地址 。 由于这些冗余的 Web 服务器 , 一个 IP 地址集合因此与同一个规范主机名相联系 。 DNS 数据库中存储着这些 IP 地址集合。 当客户对映射到某地址集合的名字发出一个 DNS 请求时 ,该服务器用 IP 地址的整个集合进行响应 , 但在每个回答中循环这些地址次序 。 因为客户通常总是向 IP 地址排在最前面的服务器发送 HTTP 请求报文 , 所以DNS 就在所有这些冗余的 Web 服务器之间循环分配了负载 。