应用层
应用层协议原理
- 研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序。例如,在
Web
应用程序中,有两个互相通信的不同的程序:一个是运行在用户主机上的浏览器程序;另一个是运行在Web
服务器主机上的Web
服务器程序。另一个例子是P2P
文件共享系统,在参与文件共享的社区中的每台主机中都有一个程序。 - 因此,当研发新应用程序时,你需要编写将在多台端系统上运行的软件。该软件能够用如
C
、Java
或Python
来编写。重要的是,你不需要写在网络核心设备如路由器或链路层交换机上运行的软件。网络核心设备并不在应用层上起作用,而仅在较低层起作用,特别是在网络层及下面层次起作用。这种基本设计,即将应用软件限制在端系统的方法,促进了大量的网络应用程序的迅速研发和部署。
网络应用程序体系结构
- 当进行软件编码之前,应当对应用程序有一个宽泛的体系结构计划。从应用程序研发者的角度看,网络体系结构是固定的,并为应用程序提供了特定的服务集合。在另一方面,应用程序体系结构由应用程序研发者设计。规定了如何在各种端系统上组织该应用程序。在选择应用程序体系结构时,应用程序研发者很可能利用现代网络应用程序中所使用的两种主流体系结构之一:客户——服务器体系结构或对等(
P2P
)体系结构 - 在客户——服务器体系结构中,有一个总是打开的主机称为服务器,它服务于来自许多其他称为客户的主机的请求。值得注意的是利用客户——服务器体系结构,客户相互之间不直接通信;例如,在
Web
应用中两个浏览器并不直接通信。客户——服务器体系结构的另一个特征是该服务器具有固定的、周知的地址,并且因为该服务器总是打开的,客户总是能够通过向服务器的IP
地址发送分组来与其联系。 - 在一个客户——服务器应用中,常常会出现一台单独的服务器主机跟不上它所有客户请求的情况。为此,配备大量主机的数据中心常被用于创建强大的虚拟服务器。
- 在一个
P2P
体系结构中,对位于数据中心的专用服务器有最小(或者没有)依赖。相反,应用程序在间断连接的主机对之间使用直接通信,这些主机对被称为对等放。这些对等方并不为服务提供商所有,相反却为用户控制的桌面机和膝上机所有,大多数对等方驻留在家庭、大学和办公室。因为这种对等方通信不必通过专门的服务器,该体系结构被称为对等方到对等方的。某些应用具有混合的体系结构,它结合了客户——服务器和P2P
的元素。例如,对于许多即使讯息应用而言,服务器被用于跟踪用户的IP
地址,但用户到用户的报文在用户主机之间(无需通过中间服务器)直接发送。 P2P
体系结构的最引人入胜的特性之一是它们的自扩展性。例如,在一个P2P
文件共享应用中,尽管每个对等方都由于请求文件产生工作负载,但每个对等方通过向其他对等方分发文件也为系统增加服务能力。P2P
体系结构也是有成本效率的,因为它们通常不需要庞大的服务器基础设施和服务器带宽。
进程通信
- 在构建网络应用程序前,还需要对运行在多个端系统上的程序是如何互相通信的情况有一个基本了解。
- 在两个不同端系统上的进程,通过跨越计算机网络交换报文而相互通信。发送进程生成并向网络中发送报文;接收进程接收这些报文并可能通过回送报文进行响应。
客户服务器进程
- 网络应用程序由成对的进程组成,这些进程通过网络相互发送报文。
- 在一对进程之间的通信会话场景中,发起通信(即在该会话开始时发起与其他进程的联系)的进程被标识为客户,在会话开始时等待联系的进程是服务器。
进程与计算机网络之间的接口
- 多数应用程序是由通信进程对组成,每对中的两个进程互相发送报文。从一个进程向另一个进程发送的报文必须通过下面的网络。进程通过一个称为套接字的软件接口向网络发送报文的报文和从网络接收报文。
- 套接字是同一台主机内应用层与运输层之间的接口。由于该套接字是建立网络应用程序的可编程接口,因此套接字也称为应用程序和网络之间的应用程序编程接口。应用程序开发者可以控制套接字在应用层端的一切,但是对该套接字的运输层端几乎没有控制权。应用程序开发者对于运输层的控制权仅限于:
- 选择运输层协议
- 也许能设定几个运输层参数,如最大缓存和最大报文段长度等。一旦应用程序开发者选择了一个运输层协议(如何可供选择的话),则应用程序就建立在由该协议提供的运输层服务之上。
进程寻址
- 为了向特定目的地发送邮政邮件,目的地需要有一个地址。类似地,在一台主机上运行地进程为了向在另一台主机上运行地进程发送分组,接收进程需要有一个地址。为了标识该接收进程,需要定义两种信息
- 主机的地址
- 在目的主机中指定接收进程地标识符
- 在因特网中,主机由
IP
地址标识。除了知道报文发送目的地的主机地址外,发送进程还必须指定运行在接收主机上的接收进程。因为一般而言一台主机能够运行许多网络应用,这些信息是需要的。目的地端口号用于这个目的。
可供应用程序使用的运输服务
- 套接字是应用程序进程和运输层协议之间的接口。在发送端的应用程序将报文推进该套接字。在该套接字的另一侧,运输层协议负责从接收进程的套接字得到该报文。
- 包括因特网在内的很多网络提供了不止一种运输层协议。当开发一个应用时,必须选择一种可用的运输层协议。
- 一个运输层协议能够为调用它的应用程序提供什么样的服务呢?大体能够从四个方面对应用程序服务要求进行分类:可靠数据传输、吞吐量、定时和安全性。
可靠数据传输
- 分组在计算机网络中可能丢失。某些应用数据丢失可能会造成灾难性的后果。因此,为了支持这些应用,必须做一些工作以确保由应用程序的一端发送的数据正确、完全地交付给应用程序的另一端。如果一个协议提供了这样的确保数据交付服务,就认为提供了可靠数据传输。运输层协议能够潜在地向应用程序提供的一个重要服务是进程到进程的可靠数据传输。当一个运输协议提供这种服务时,发送进程只要将其数据传递给套接字,就可以完全相信该数据将能够无差错地到达接收进程。
- 当一个运输层协议不提供可靠数据传输时,由发送进程发送的某些数据可能到达不了接收进程。
吞吐量
- 在沿着一条网络路劲上的两个进程之间的通信会话场景中,可用吞吐量就是发送进程能够向接收进程交付比特的速率。因为其他会话将共享沿着该网络路径的带宽,并且因为这些会话将会到达和离开,该可用吞吐量将随时间波动。这些观察导致另一种自然的服务,即运输层协议能够以某种特定的速率提供确保的可用吞吐量。使用这种服务,该应用程序能够请求
r
比特/秒的确保吞吐量,并且该运输协议能够确保可用吞吐量总是为至少r
比特/秒。这样的确保吞吐量的服务将对许多应用程序有吸引力。 - 具有吞吐量要求的应用程序被称为带宽敏感的应用。
- 带宽敏感的应用具有特定的吞吐量要求,而弹性应用能够根据当时可用的带宽或多或少地利用可供使用地吞吐量。
定时
- 怨恨村官协议也能够提供定时保证。如同具有吞吐量保证那样,定时保证能够以多种形式实现。
安全性
- 运输层协议能够为应用程序提供一种或多种安全性服务。例如,在发送主机中,运输协议能够加密由发送进程传输的所有数据,在接收主机中,运输层协议能够将数据交付刚给接收进程之前解密这些数据。这种服务将在发送和接收进程之间提供机密性,以防该数据以某种方式在这两个进程之间被观察到。运输协议还能提供除了机密性以外的其他安全性服务,包括数据完整性和端点鉴别。
因特网提供的运输服务
- 因特网(更一般的是
TCP/IP
网络)为应用程序提供两个运输层协议,即UDP
和TCP
。当你为因特网创建一个新的应用时,首先要做出的决定是,选择UDP
还是选择TCP
。每个协议为调用它们的应用程序提供了不同的服务集合。
TCP
服务
TCP
服务模型包括面向连接服务和可靠数据传输服务。当某个应用程序调用TCP
作为其运输协议时,该应用程序就能获得来自TCP
的这两种服务。- 面向连接的服务:在应用层数据报文开始流动之前,
TCP
让客户和服务器互相交换运输层控制信息。这个所谓的握手过程体系客户和服务器,让它们为大量分组的到来做好准备。在握手阶段后,一个TCP
连接就在两个进程的套接字之间建立了。这条链路是全双工的,即连接双方的进程可以在此连接上同时进行报文收发。当应用程序结束报文发送时,必须拆除该连接。 - 可靠的数据传送服务:通信进程能够依靠
TCP
,无差错,按适当顺序交付所有发送的数据。当应用程序的一端将字节流传金套接字时,它能够依靠TCP
将相同的字节流交付给接收方的套接字,而没有字节的丢失和冗余。
- 面向连接的服务:在应用层数据报文开始流动之前,
TCP
协议还具有拥塞控制机制,这种服务不一定能为通信进程带来直接好处,但能为因特网带来整体好处。当发送发和接收方之间的网络出现拥塞时,TCP
的拥塞控制机制会抑制发送进程(客户或服务器)。
UDP
服务
UDP
是一种不提供不必要服务的轻量级运输协议,它仅提供最小服务。UDP
是无连接的,因此在两个进程通信前没有握手过程。UDP
协议提供一种不可靠数据传送服务,也就是说,当进程将一个报文发送UDP
套接字时,UDP
协议并不保证该报文将到达接收进程。不仅如此,到达接受的报文也可能是乱序到达的。UDP
没有包括拥塞控制机制,所以UDP
的发送端可以用它选定的任何速率向其下层注入数据。
因特网运输协议所不提供的服务
- 我们已经从4个方面组织了运输协议服务:可靠数据传输、吞吐量、定时和安全性。
TCP
提供了可靠的端到端数据传送。并且TCP
在应用层可以很容易地用SSL
来加强以提供安全服务。但是在对TCP
和UDP
的简要描述中,明显地漏掉了对吞吐量或定时保证的讨论,即这些服务目前的因特网运输协议并没有提供。
应用层协议
- 应用层协议定义了运行在不同端系统上的应用程序如何相互传递报文。特别是应用层协议定义了:
- 交换的报文类型,例如请求报文和响应报文
- 各种报文类型的语法,如报文中的各个字段及这些字段是如何描述的
- 字段的语义,即这些字段中的信息的含义
- 确定一个进程何时以及如何发送报文,对报文进行响应的规则。
- 有些应用层协议是由
RFC
文档定义的,因此它们位于公共域中。例如,Web
的应用层协议HTTP
就作为一个RFC
可供使用。如果浏览器开发者遵守HTTP RFC
规则,所开发出的浏览器就能访问任何遵从该文档标准的Web
服务器并获取相应Web
页面。
Web
和HTTP
HTTP
概况
Web
的应用层协议是超文本传输协议,它是Web
的核心,在[RFC 1945
]和[RFC 2616
]中进行了定义。HTTP
由两个程序实现:一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统中,通过交换HTTP
报文进行会话。HTTP
定义了这些报文的结构以及客户和服务器进行报文交换的方式。Web
页面是由对象组成的。一个对象只是一个文件,诸如一个HTML
文件,一个JPEG
图形、一个Java
小程序或一个视频片段这样的文件。且它们可通过一个URL
地址寻址。多数Web
页面含有一个HTML
基本文件以及几个引用对象。HTTP
定义了Web
客户向Web
服务器请求Web
页面的方式,以及服务器向客户传送Web
页面的方式。当用户请求一个Web
页面时,浏览器向服务器发出对该页面中所包含对象的HTTP
请求报文,服务器接收到请求并用包含这些对象的HTTP
响应报文进行响应。HTTP
使用TCP
作为它的支撑运输协议。HTTP
客户首先发起一个与服务器的TCP
连接。一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问TCP
。- 服务器向客户发送被请求的文件,而不存储任何关于该客户的状态信息。因为
HTTP
服务器并不保存关于客户的任何信息,所以我们说HTTP
是一个无状态协议。
非持续连接和持续连接
- 当客户-服务器的交互是经
TCP
进行的,应用程序的研制者就需要做一个重要决定,即每个请求/响应对是经一个单独的TCP
连接发送,还是所有的请求及其响应经相同的TCP
连接发送呢?采用前一种方法,该应用程序被称为使用非持续连接;采用后一种方法,该应用程序被称为使用持续连接。尽管HTTP
在其默认方式下使用持续连接,HTTP
客户和服务器也能配置成使用非持续连接。
采用非持续连接的HTTP
- 每个
TCP
连接在服务器发送一个对象后关闭,即该连接并不为其他的对象而持续下来。值得注意的是每个TCP
连接只传输一个请求报文和一个响应报文。 - 往返时间的定义:该时间是指一个短分组从客户到服务器然后再返回客户所花费的时间。
RTT
包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延。
采用持续连接的HTTP
- 非持续连接有一些缺点。第一,必须为每一个请求的对象建立和维护一个全新的连接。对于每个这样的连接,在客户和服务器中都要分配
TCP
的缓冲区和保持TCP
变量,这给Web
服务器带来了严重的负担。第二,每一个对象经受两倍RTT
的交付时延,即一个RTT
用于拆功能键TCP
,另一个RTT
用于请求和接收一个对象。 - 在采用
HTTP1.1
持续连接的情况下,服务器在发送响应后保持该TCP
连接打开。在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送。特别是,一个完整的Web
页面可以用单个持续TCP
连接进行传送。更有甚者,位于同一台服务器的多个Web
页面在从该服务器发送给同一个客户时,可以在单个持续TCP
连接上进行。对对象的这些请求可以一个接一个地发出,而不必等待对未决请求(流水线)的回答。一般来说,如果一条连接经过一定时间间隔(一个可配置的超时间隔)仍未被使用,HTTP
服务器就关闭该连接。HTTP
的默认模式是使用带流水线的持续连接。
HTTP
报文格式
HTTP
规范包含了对HTTP
报文格式的定义。HTTP
报文有两种:请求报文和响应报文。
1.HTTP请求报文
-
GET /somedir/page.html HTTP/1.1 Host:www.someschool.edu Connection:close User-agent:Mozilla/5.0 Accept-Language:fr
-
该报文由5行组成,每行由一个回车和换行符结束。最后一行后再附加一个回车换行符。虽然这个特定的报文仅有5行,但一个请求报文能够具有更多的行或者至少为一行。
HTTP
请求报文的第一行叫做请求行,其后继的行叫做首部行。请求行有3个字段:方法字段、URL
字段和HTTP
版本字段。方法字段可以取几种不同的值,包括GET
、POST
、HEAD
、PUT
和DELETE
。绝大部分的HTTP
请求报文使用GET
方法。当浏览器请求一个对象时,使用GET
方法,在URL
字段带有请求对象的标识。 -
首部行Host:
www.someschool.edy
指明了对象所在的主机。该首部行提供的信息是Web
代理高速缓存所要求的。通过包含Connection:close
首部行,该浏览器告诉服务器不要麻烦地使用持续连接,它要求即向服务器在发送完被请求的对象后就关闭这条连接。User-agent
:首部行用来指明用户代理,即向服务器发送请求的浏览器的类型。这个首部行可以让服务器有效地为不同类型的用户代理实际发送相同对象的不同版本。最后,Accept-language
:首部行表示用户想得到该对象的法语版本;负责,服务器应当发送它的默认版本。 -
请求报文的通用格式:
- 在首部行之后有一个实体(
entity body
)。使用GET
方法时实体为空,而使用POST
方式时才使用该实体。当用户提交表单时,HTTP
客户常常使用POST
方法。如果方法字段的值为POST
时,则实体中包含的就是用户在表单字段中的输入值。 HTML
表单经常使用GET
方法,并在所请求的URL
中包含输入的数据。HEAD
方法类似于GET
方法。当服务器收到一个使用HEAD
方法的请求时,将会用一个HTTP
报文进行响应,但是并不返回请求对象。应用程序开发者常用HEAD
方法进行调试跟踪。PUT
方法常与Web
发行工具联合使用,它允许用户上传对象到指定的Web
服务器上指定的路径。Delete
方法允许用户或者应用程序删除Web
服务器上的对象。
- 在首部行之后有一个实体(
2.HTTP
响应报文
-
下面提供一条典型的
HTTP
响应报文。该响应报文可以是刚刚讨论的例子中的请求报文的响应HTTP/1.1 200 OK Connection:close Date:Tue,18 Aug 2015 15:44:04 GMT Server:Apache/2.2.3 (CentOS) Last-Modified:Tue,18 Aug 2015 15:11:03 GMT Content-Length:6821 Content-Type:text/html (data data data data data...)
-
这个响应报文,有三个部分:一个初始状态行(
status line
),6个首部行(header line
),然后是实体(entity body
)。状态行有3个字段:协议版本字段、状态码和相应状态信息。一些常见的状态码和相关的短语:- 200
OK
:请求成功,信息在返回的响应报文中 301 Moved Permanently
:请求的对象已经被永久转移了,新的URL
定义在响应报文的Location
:首部行中。客户软件将自动获取新的URL
。400 Bad Request
:一个通用差错代码,指示该请求不能被服务器理解404 Not Found
:被请求的文档不在服务器上505 HTTP Version Not Supported
:服务器不支持请求报文使用的HTTP
协议版本
- 200
-
Connection close
:首部行告诉客户,发送完报文后将关闭该TCP
连接。 -
Date
:首部行指示服务器产生并发送该响应报文的日期和时间。 -
Server
:首部行指示该报文是由一台Apache Web
服务器产生的,它类似于HTTP
请求报文中的User-agent
:首部行 -
Last-Modified
:首部行指示了对象创建或者最后修改的日期和时间。 -
Last-Modified
:首部行对即可能在本地客户页可能在网络缓存服务器上的对象缓存来说非常重要。 -
Content-Length
:首部行指示了被发送对象中的字节数。 -
Content-Type
:首部行指示了实体中的对象是HTML
文本。
用户与服务器的交互:cookie
cookie
技术有4个组件:- 在
HTTP
响应报文中的一个cookie
首部行 - 在
HTTP
请求报文中的一个cookie
首部行 - 在用户端系统中保留有一个
cookie
文件,并由用户的浏览器进行管理 - 位于
Web
站点的一个后端数据库
- 在
Web缓存
Web
缓存器也叫做代理服务器,它是能够代表初始Web
服务器来满足HTTP
请求的网络实体。Web
缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象的副本。
条件GET方法
- ①请求报文使用
GET
方法;并且②请求报文中含有一个"If-Modified-Since
"首部行。那么,这个HTTP
请求报文就是一个GET
请求报文。
因特网中的电子邮件
- 电子邮件有3个主要组成部分:用户代理、邮件服务器和简单邮件传输协议