Web 和 HTTP

20 世纪 90 年代以前, 因特网还不为学术界和研究界之外所知。

到了 20 世纪 90 年代初, 一个主要的新型应用即万维网登上了 舞台, Web 是一个引起公众注意的因特网应用, 它极大地改变了人们与工作环境内外交流的方式。

它将因特网从只是很多从只是很多数据网之一的地位提升为仅有的一个数据网。

也许对大多数用户来说,最具有吸引力的是 Web 的按需操作。 当用户需要时,就能得到所想要的内容,这不同于无线电广播和电视,迫使用户只能收听、收看内容提供者提供的节目。

除了可以按需操作以外, Web 还有很多让人们喜欢的特性。任何人使信息在 Web 上可用都非常简单, 即只需要极低的费用就能成为出版人

超链接和搜索引擎帮助我们在 Web 站点的海洋里导航, 图形化的界面刺激着我们的感官。表单、Java小程序和其他的装置,使我们可以与 Web 页面和站点进行交互。

2.2.1 HTTP 概况

web 的应用层协议是超文本传输协议, 它是 Web 的核心。

在 [RFC 1945] 和 [RFC 2616] 中进行了定义。 HTTP 由两个程序实现: 一个客户程序和一个服务器程序。

客户程序和服务器程序运行在不同的端系统中,通过交换 HTTP 报文进行会话, HTTP 定义了这些报文的结构以及客户和服务器进行报文交换的方式。

在详细解释 HTTP 之前,先熟悉某些 Web术语。

Web 页面:

web page, 也叫文档

是由对象组成的,一个对象(object)这是一个文件,诸如一个 HTML 文件,一个 JPEG 图形, 一个 Java 小程序 或一个 视频片段这样的文件, 且它们可通过一个 URL 地址寻址

多数 Web 页面含有一个 HTML 基本文件(base HTML file)以及几个引用对象。HTML 基本文件通过对象的 URL 地址引用页面中的其他对象。 每个URL 地址由两部分组成: 存放对象的服务器主机名和对象的路径名。

例如:

URL地址 http:www.someSchool.edu/ someDepartment/picutre.gif
www.someSchool.edu 就是主机名, 之后的就是路径名。

因为 Web 浏览器(Web browser) 实现了 HTTP 的客户端,所以在 Web 环境中我们经常交替使用 “ 浏览器” 和 “客户” 这两个术语。

Web 服务器实现了 HTTP的服务器端, 它用于存储 Web 对象,每个对象由 URL 寻址。流行的 Web 服务器有 Apache 和 Microsoft Internet Information Server。

在这里插入图片描述
HTTP 定义了 Web 客户向 Web 服务器请求 Web 页面的方式,以及服务器向客户传送 Web 页面的方式。

基本思想:当用户请求了一个 Web 页面(如点击了一个超链接)时,浏览器向服务器发出对该页面中所包含对象的 HTTP 请求报文, 服务器接收到请求并用包含这些对象的 HTTP 响应报文进行响应。

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

客户向它的套接字接口发送一个请求报文, 该报文就脱离了客户控制并进入 TCP的控制。

TCP 为 HTTP 提供可靠数据传输服务。 这意味着, 一个客户进程发出的每个 HTTP 请求报文最终能完整地到达服务器; 类似地, 服务器进程发出的每个 HTTP 响应报文最终能完整到达客户。

这里我们看到了分层体系结构最大的优点,即 HTTP 协议不用担心数据丢失,也不关注 TCP 从网络的数据丢失和乱序故障中恢复的细节。

那是 TCP 以及协议栈较低层的工作。

注意到下列现象很重要: 服务器向客户发送被请求的文件,而不存储任何关于该客户的状态信息。 假如某个特定的客户在短短的几秒钟内两次请求同一个对象, 服务器并不会因为刚刚为该客户提供了该对象就不再做出反应,而是重新发送该对象, 就像服务器已经完全忘记不久之前所做的事一样。因为 HTTP服务器并不保存关于客户的任何信息, 所以我们说 HTTP 是一个无状态协议(stateless protocol)。

我们也注意到了 Web 使用了客户-服务器应用程序体系结构, Web 服务器总是打开的,具有一个固定的 IP 地址, 且它服务于可能来自数以百万计的不同浏览器的请求。

2.2.2 非持续连续和持续连续

在许多因特网应用程序中, 客户和服务器在一个相当长的时间范围内通信,其中客户发出一系列请求并且服务器对每个请求进行响应。

依据应用程序以及该应用程序的使用方式, 这一系列请求可以以规则的间隔周期性地或者间断性地一个接一个发出。 当这种客户-服务器的交互是经过 TCP 进行的, 应用程序的研制者就需要做一个重要决定, 即每个请求/ 响应对是经一个单独的 TCP 连接发送,还是所有的请求及其响应经相同的 TCP 连接发送呢?

  • 采用前一种方法: 该应用程序被称为使用非持续连接(non-persistent connection);
  • 采用后一种方法:该应用程序被称为持续连接。
  1. 采用非持续连接的 HTTP

在非持续连接情况下, 从服务器向客户传送一个 Web 页面的步骤。 假设该页面含有一个 HTML 基本文件和 10个 JPEG 图形, 并且这 11 个对象位于同一台服务器上。

该 HTML 文件的 URL为 :http://www.someSchool.edu / someDepartment/ home.index

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

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

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

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

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

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

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

当浏览器收到 Web 页面后,显示给用户。 两个不同的浏览器也许会以不同的方式解释(即向用户显示)该页面。

HTTP 与 客户如何解释一个 Web 页面毫无关系, HTTP 规范(【RFC 1945】 和 【RFC 2616】)仅定义了在 HTTP 客户程序与 HTTP 服务器程序之间的通信协议

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

在上面描述的步骤中,我们有意没有明确客户获得这 10 个 JPEG 图形对象是使用 10 个 串行的 TCP 连接, 还是某些 JPEG 对象使用了一些并行的 TCP 连接。

事实上, 用户能够配置现代浏览器以控制并行度。 在默认方式下,大部分浏览器打开 5 ~ 10 个 并行的 TCP 连接, 而每条连接处理一个请求响应事务。

如果用户愿意,最大并行连接数可以设置为 1, 这样 10条连接就会串行建立。

连接可以并行?

我们来简单估算一下从客户请求 HTML 基本文件起到该客户收到整个文件止所花费的时间。 为此, 我们给出往返时间 (Round-Trip Time, RTT) 的定义, 该时间是指一个短分组从客户到服务器然后再返回客户所花费的时间。

RTT 包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延。

现在考虑当用户点击超链接时会发生什么现象。

如图所示,

这引起浏览器在它和 Web 服务器之间发起一个 TCP 连接; 这涉及一次 “三次握手过程”, 即客户向服务器发送一个小 TCP 报文段, 服务器用一个小 TCP 报文段做出确认 和 响应, 最后,客户向服务器返回确认。

三次握手中前两个部分所耗费的时间占用了一个 RTT。 完成了三次握手前两个部分之后,客户结合三次握手的第三部分(确认)向该 TCP 连接发送一个 HTTP 请求报文。 一旦该请求报文到达服务器, 服务器就在该 TCP 连接上发送HTML 文件。该 HTTP 请求 / 响应用去了另一个 RTT。

因此,粗略地将, 总的响应时间就是两个 RTT 加上服务器传输 HTML 文件的时间。在这里插入图片描述

  1. 采用持续连接的 HTTP

非持续连接的缺点:

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

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

特别的是, 一个完整的 Web 页面可以用单个持续 TCP 连接进行传送。 更有甚者, 位于同一台服务器的多个 Web 页面在从该服务器发送给同一个客户时, 可以在单个持续 TCP 连接上进行, 可以一个接一个地发出对对象的这些请求, 而不必等待对未决请求(流水线)的回答。

一般来说, 如果一条连接经过一定时间间隔(一个可配置的超时间隔)仍未被使用, HTTP服务器就关闭该连接,HTTP的默认模式是使用带流水线的持续连接。

2.2.3 HTTP报文格式

HTTP规范【 RFC 1945; RFC 2616】包含了对 HTTP报文格式的定义。 HTTP报文有两种:请求报文和响应报文。
  1. HTTP请求报文:

在这里插入图片描述如图所示:

  • 首先,我们看到该报文是用普通的 ASCLL 文本书写的。
  • HTTP 请求报文的第一行为请求行(request line), 其后继的行叫做首部行(header line)。
  • 请求行有 3 个字段:方法字段、URL 字段和 HTTP 版本字段。
  • 方法字段可以取几种不同的值, 包括 GET、 POST 、HEAD、PUT 和 DELETE。
  • 绝大部分的 HTTP请求报文使用 GET 方法, 当浏览器请求一个对象时,使用 GET方法, 在 URL 字段带有请求对象的标识。

在本例中,该浏览器正在请求对象 /somedir/page.html 。 其版本字段是自解释的; 在本例中,浏览器实现的是 HTTP /1.1 版本。

  1. 首部行:

在这里插入图片描述

指明了对象所在的主机, 该首部行提供的信息是 Web 代理高速缓存所要求的。

  1. 通过包含 Connection: close 首部行, 该浏览器告诉服务器不希望麻烦地使用持续连接, 它要求服务器在发送完被请求的对象后就关闭这条连接。

  2. User-agent: 首部行用来指明用户代理, 即向服务器发送请求的浏览器的类型。 这里浏览器是 Mozilla/5.0 , 即 Firefox 浏览器, 这个首部行是有用的, 因为服务器可以有效地为不同类型的用户代理实际发送相同对象的不同版本。

  3. Accept-language : 首部行 表示用户想得到该对象的法语版本, 服务器应当发送它的默认版本。

  4. Accept-language: 首部行仅是 HTTP 中可用的众多内容协商首部之一。

报文的通用格式

在这里插入图片描述

在首部行后有个 “ 实体主体(entity body)”, 使用 GET 方法实体主体为空, 而使用 POST 方法时才使用该实体主体。

当用户提交表单时, HTTP 客户常常使用 POST 方法。 例如, 当用户向搜索引擎提供搜索关键词时, 使用 POST 报文时, 用户仍可以像服务器请求一个 Web 页面, 但 Web 页面的特定内容依赖于用户在表单字段中输入的内容, 如果方法字段的值为 POST 时, 则实体主体包含的就是用户在表单字段中的输入值。

当然,用表单生成的请求报文不是必须使用 POST 方法, HTML 表单经常使用 GET 方法, 并在(表单字段中)所请求的 URL 中包括输入的数据。

例如,一个表单使用 GET 方法, 它有两个字段, 分别填写的是 “ monkeys” 和 “ bananas” , 这样,该 URL 结构为 www.somesite.com / animalsearch?monkeys&bananas。

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

PUT 方法常与 Web 发行工具联合使用,它允许用户上传对象到指定的 Web 服务器上指定的路径(目录),PUT 方法也被那些需要向 Web 服务器上传对象的应用程序使用。

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

HTTP 响应报文

该响应报文时对刚刚讨论的例子中的请求报文的响应:

在这里插入图片描述在这里插入图片描述

这个响应报文有三个部分:

  • 一个初始状态行(status line)
  • 6 个首部行(header line)
  • 实体主体 (entity body)

实体主体是报文的主要部分, 即它包含了所请求的对象本身。

状态行有三个字段:协议版本字段、状态码和相应状态信息。 在这个例子中,状态行指示服务器正在使用 HTTP/1.1 , 并且一切正常(即服务器已经找到并正在发送所请求的对象)。

首部行:

  1. 服务器用 Connection:close 首部行告诉客户,发送完报文后将关闭该 TCP 连接。
  2. Date:首部行指示服务器产生并发送该响应报文的日期和时间。这里的时间不是指对象创建或者最后修改的时间; 而是服务器从它的文件系统中检索到该对象, 插入到响应报文,并发送该响应报文的时间。
  3. Server:首部行指示该报文是由一台 Apache Web 服务器产生的, 类似 HTTP请求报文中的 User-agent: 首部行。
  4. last-Modified: 首部行指示了对象创建或者最后修改的对象缓存来说非常重要。
  5. Content-Length:首部行指示了被发送对象的字节数。
  6. Content-Type: 首部行指示了实体主体中的对象是 HTML 文本(该对象类型应该正式地由 Content-Type:首部行而不是用文件扩展名来指示)
    在这里插入图片描述

看完例子: 我们再来查看响应报文的通用格式, 该通用格式能够与前面例子的响应报文对应起来。 补充说明状态码和它们相对应的短语。

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

在这里插入图片描述在这里插入图片描述

HTTP规范中定义了很多可以被浏览器、Web服务器和 Web 缓存服务器插入的首部行。

浏览器是如何决定在一个请求报文中包含哪些首部行的呢? Web 服务器又是如何决定在一个响应报文中包含哪些首部行的呢?

浏览器产生的首部行与许多因素有关,包括浏览器的类型和协议版本、浏览器的用户配置、浏览器当前是否有一个缓存的但是可能超期的对象版本。Web 服务器的表现也类似:在产品、版本和配置上都有差异,所有这些都会影响响应报文中包含的首部行。

2.2.4 用户与服务器的交互:cookie

我们之前说到 HTTP 服务是无状态的, 这简化了服务器的设计,并且允许工程师们去开发可以同时处理数以千计的 TCP 连接的高性能 Web 服务器。

然而一个 Web 站点通常希望能够识别用户,可能是因为服务器希望限制用户的访问,或者因为它希望把内容与用户身份联系起来, 为此,HTTP 使用了cookie, cookie 在 【RFC 6265】中定义,它允许站点对用户进行跟踪, 目前大多数 Web 站点都使用了 cookie。在这里插入图片描述
如图所示: cookie技术有 4 个组件:

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

cookie 可以用于标识一个用户,用户首次访问一个站点时, 可能需要提供一个用户表示,在后继会话中,浏览器向服务器传递一个 cookie 首部, 从而向该服务器标识了用户。

因此 cookie 可以在无状态的 HTTP 之上建立一个用户会话层。 例如, 当用户向一个基于 Web 的电子邮件系统注册时, 浏览器向服务器发送 coolie 信息, 允许该服务器在用户与应用程序会话的过程中标识该用户。

尽管 cookie常常能简化用户的因特网购物活动,但是它的使用仍具有争议,因为它们被认为是对用户隐私的一种侵害, 如我们刚才所见,结合 cookie 和用户提供的账号信息, Web 站点可以知道许多有关用户的信息,并可能将这些信息卖给第三方。

2.2.5 Web 缓存

在这里插入图片描述

Web 缓存器(web cache) 也叫代理服务器(proxy server), 它是能够代表初始 Web 服务器来满足 HTTP 请求的网络实体。

Web 缓存器有自己的磁盘存储空间, 并在存储空间中保存最近请求过的对象的副本。

如上图所示, 可以配置用户的浏览器,使得用户的所有 HTTP 请求首先指向 Web 缓存器。 一旦某浏览器被配置, 每个对某对象的浏览器请求首先被定向到该 Web 缓存器。

值得注意的是 Web 缓存器是服务器同时又是客户, 当它接收浏览器的请求并发回响应时, 它是一个服务器, 当它向初始服务器发出请求并接收响应时,它是一个客户。

在这里插入图片描述在这里插入图片描述

在因特网上部署 Web 缓存器有两个原因。

  • 首先, Web 缓存器可以大大减少对客户请求的响应时间, 特别是当客户与初始服务器之间的瓶颈带宽远低于客户与 Web 缓存器之间的瓶颈带宽时更是如此。 如果在客户与 Web 缓存器之间有一个高速连接, 并且如果用户所请求的对象在 Web 缓存器上, 则 Web 缓存器可以迅速将该对象交付给用户

是不是很熟悉,有点像内存和 CPU 之间的高速缓存。作用是一样的。

  • Web 缓存器能够大大减少一个机构的接入链路到因特网的通信量。 通过减少通信量, 该机构(如一家公司或者大学)就不必急于增加带宽,从而降低了费用。
  • 此外, Web 缓存器能从整体上大大减低因特网上的Web 流量,从而改善了所有应用的性能。

为了深入理解缓存器带来的好处, 我们考虑下面的例子:
在这里插入图片描述
该图有两个网络:

假设:

  • 对象的平均长度为 1MB。
  • 从机构内的浏览器对这些初始服务器的平均访问速率为每秒 15个请求。
  • HTTP请求报文小到可以忽略,不会在网络中以及接入链路上产生什么通信量。
  • 从因特网接入链路一侧的路由器转发 HTTP 请求报文(在一个IP 数据报中) 开始,到它收到其响应报文为止的时间平均为 2秒。 我们先将该持续时延称为“ 因特网时延”。

总响应时间 = 局域网时延 + 接入时延 + 因特网时延

总的响应时间, 即从浏览器请求一个对象到接收该对象为止的时间。

接入时延:两台路由器之间的时延

局域网的流量强度为:
在这里插入图片描述
接入链路的流量强度为:
在这里插入图片描述

注意: MB 和 Mb 不一样, 一个是 M byte, 一个是 M 比特

局域网上强度为 0.15 的通信量最多导致数十毫秒的时延, 因此我们可以忽略局域网时延。

然而,如之前所讨论,如果流量强度接近于 1, 链路上的时延会变得非常大且无限增长。 我们要改进时间响应特性。


我们很自然想到的一种办法是增加接入链路的速率,比如增加到 100Mbps, 那么流量强度减少到 0.15, 这样,两台路由器之间的链路时延也可以忽略了。

这时,总的时延将大约为 2 秒钟, 即因特网时延, 但是这样代价很高, 毕竟增加到 100 Mbps 不是光拿嘴说说就做到的。

那有没有其他办法?

即在机构网络中安装一个 Web 缓存器在这里插入图片描述
实践中的命中率(即由一个缓存器所满足的请求的比率)通常在 0.2 ~ 0.7 之间。

我们假设该机构的命中率为 0.4, 因为客户和缓存连接在一个相同的高速局域网上,这样 40 % 的请求将几乎立即会由缓存器得到响应。(不需要通过与初始服务器相连),时延约在 10ms 以内。

然而剩下的 60% 请求仍然要由初始服务器来满足, 但是只有 60 % 被请求对象通过接入链路, 在接入链路的流量强度从 1.0 降到 0.6 。

一般而言,在 15 Mbps 链路上,当流量强度小于 0.8 时对应的时延较小, 约为几十毫秒。 这个时延与 2 秒因特网时延相比是微不足道的。

考虑这些,平均时延因此为
在这里插入图片描述
略大于 1.2 秒,甚至比我们增加 100Mbps 链路效果还好,当然选择购买和安装 Web 缓存器。 而且 Web 缓存器成本较低, 很多缓存器使用了运行在廉价 PC 上的公共域软件。

在这里插入图片描述

2.2.6 条件 GET 方法

高速缓存确实好,但是这样导致放在缓存器中的对象可能是陈旧的。

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

如果:

  • (1)请求报文使用 GET 方法;
  • (2)请求报文中包含一个 “if-Modified-Since:” 首部行

那么,这个 HTTP请求报文就是一个条件 GET 请求报文。

为了说明 GET 方法的操作方式, 我们看一个例子。

首先,一个代理缓存器代表一个请求浏览器,向某 Web 服务器发送一个请求报文:
在这里插入图片描述
其次,该 Web 服务器向缓存器发送具有被请求的对象的响应报文:
在这里插入图片描述

该缓存器缓存了该对象,重要的是: 缓存器在存储该对象时也存储了最后修改日期。

一个星期后, 另一个用户经过该缓存器请求一个同一个对象,该对象仍在这个缓存器中,由于在过去的一星期中位于 Web 服务器上的该对象可能已经被修改了, 该缓存器通过发送一个条件 GET 执行最新检查。

具体来说, 该缓存器发送:

在这里插入图片描述
指的注意的是 : if-Modified-Since:

首部行的值正好等于一星期前服务器发送的响应报文中的 Last-Modified: 首部行的值。该条件 GET 报文告诉服务器, 仅当自指定日期之后该对象被修改过,才发送该对象。 假设该对象没有被修改过。 Web 服务器向该缓存器发送一个响应报文:

在这里插入图片描述
作为该条件 GET 方法的响应,该 Web 服务器仍发送一个响应报文,但并没有在该响应报文中包含所请求的对象。

包含该对象只会浪费带宽,并增加用户感受到的响应时间, 特别是该对象很大时,值得注意的是在最后的响应报文中,状态行中为 304 Not Modified, 它告诉缓存器可以使用该对象, 能向请求的浏览器转发它(该代理缓存器)缓存的该对象副本。

那不是还是要每次都向初始服务器发送请求吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值