第二章应用层

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

2.1 应用层协议原理

研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序。

2.1.1 网络应用程序体系结构

  • 在这里插入图片描述

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

  • 现代网络应用程序中两种主流体系结构:客户-服务器体系结构(client-server architecture)P2P 体系结构(P2P architecture)

  • 在客户-服务器体系结构(client-server architecture)中,有一个总是打开的主机称为服务器,它服务于来自许多其他称为客户的主机的请求。

  • 值得注意的是利用客户-服务器体系结构,客户相互之间不直接通信

  • 客户-服务器体系结构的另一个特征是该服务器具有固定的、周知的地址,该地址称为IP地址

  • 具有客户-服务器体系结构的非常著名的应用程序包括Web、FTP、Telnet和电子邮件

  • 在一个P2P 体系结构中,对位于数据中心的专用服务器有最小的(或者没有)依赖

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

  • P2P体系结构应用包括括文件共享(例如BitTorrent)、对等方协助下载加速器(例如迅雷)、因特网电话和视频会议(例如Skype)

需要提及的是,某些应用具有混合的体系结构,它结合了客户-服务器和P2P的元素

  • P2P体系结构的自扩展性(self-scalability):在一个P2P文件共享应用中,尽管每个对等方都由于请求文件产生工作负载,但每个对等方通过向其他对等方分发文件也为系统增加服务能力

2.1.2 进程通信

在操作系统中,进行通信的实际上是进程(process)而不是程序
一个进程可以被认为是运行在端系统中的一个程序
当多个进程运行在相同的端系统上时,它们使用进程间通信机制相互通信

1. 客户和服务器进程
  • 对每对通信进程,我们通常将这两个进程之一标识为客户(client),而另一个进程标识为服务器(serve)
  • 对于Web而言,浏览器是一个客户进程,Web服务器是一台服务器进程
  • 对于P2P文件共享,下载文件的对等方标识为客户,上载文件的对等方标识为服务器。
  • 定义客户和服务器进程如下:
    • 在一对进程之间的通信会话场景中,发起通信(即在该会话开始时发起与其他进程的联系)的进程被标识为客户,在会话开始时等待联系的进程是服务器。
2. 进程与计算机网络之间的接口
  • 进程通过一个称为套接字(socket)的软件接口向网络发送报文和从网络接收报文
  • 在这里插入图片描述
  • 如图2-3所示,套接字是同一台主机内应用层与运输层之间的接口
  • 套接字是建立网络应用程序的可编程接口,因此套接字也称为应用程序和网络之间的应用程序编程接口(Application Programming Interface, API)
  • 应用程序开发者可以控制套接字在应用层端的一切,但是对该套接字的运输层端几乎没有控制权
  • 应用程序开发者对于运输层的控制仅限于:
    • 1.选择运输层协议
    • 2.也许能设定几个运输层参数,如最大缓存和最大报文段长度
3. 进程寻址
  • 在一台主机上运行的进程为了向在另一台主机上运行的进程发送分组,接收进程需要有一个地址
  • 为了标识该接收进程,需要定义两种信息:
    • 1.主机的地址,IP地址用于这个目的
    • 2.在目的主机中指定接收进程的标识符,目的地端口号(port number)用于这个目的
  • 在因特网中,主机由其IP地址(IP address)标识
  • IP地址是一个32比特的量且它能够唯一地标识该主机

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

我们大体能够从四个方面对应用程序服务要求进行分类:可靠数据传输、吞吐量、定时和安全性。

1.可靠数据传输
  • 分组在计算机网络中可能丢失
  • 数据丢失可能会造成灾难性的后果
  • 可靠数据传输(reliable data transfer):一个提供可靠数据传输的协议应确保由应用程序的一端发送的数据正确、完全地交付给该应用程序的另一端
  • 运输层协议能够潜在地向应用程序提供的一个重要服务是进程到进程的可靠数据传输。当一个运输协议提供这种服务时,发送进程只要将其数据传递进套接字,就可以完全相信该数据将能无差错地到达接收进程。
  • 容忍丢失的应用(loss-tolerant application):可以接受由发送进程发送的某些数据可能到达不了接收进程,如交谈式音频/视频,它们能够承受一定量的数据丢失
2.吞吐量
  • 运输层协议能够以某种特定的速率提供确保的可用吞吐量。使用这种服务,该应用程序能够请求r比特/秒的确保吞吐量,并且该运输协议能够确保可用吞吐量总是为至少r比特/秒。
  • 具有吞吐量要求的应用程序被称为带宽敏感的应用(bandwidth-sensitive application)
  • 弹性应用(elastic application)能够根据当时可用的带宽或多或少地利用可供使用的吞吐量。
3.定时
  • 运输层协议也能提供定时保证
  • 定时保证能够以多种形式实现,例如:发送方注入进套接字中的每个比特到达接收方的套接字不迟于100ms。
4.安全性
  • 运输协议能够为应用程序提供一种或多种安全性服务

2.1.4 因特网提供的运输服务

因特网为应用程序提供两个运输层协议,即UDPTCP
图2-4显示了某些所选的应用程序的服务要求。

在这里插入图片描述

1. TCP服务

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

  • 面向连接的服务:
    • 握手:在应用层数据报文开始流动之前,TCP让客户和服务器互相交换运输层控制信息
    • 这个所谓的握手过程提醒客户和服务器,让它们为大量分组的到来做好准备
    • 在握手阶段后,一个TCP连接(TCP connection)就在两个进程的套接字之间建立了
    • 这条连接是全双工的,即连接双方的进程可以在此连接上同时进行报文收发。
    • 挥手:当应用程序结束报文发送时,必须拆除该连接
  • 可靠的数据传送服务:
    • 通信进程能够依靠TCP,无差错、按适当顺序交付所有发送的数据。
    • 当应用程序的一端将字节流传进套接字时,它能够依靠TCP将相同的字节流交付给接收方的套接字,而没有字节的丢失和冗余。
  • TCP协议还具有拥塞控制机制,当发送方和接收方之间的网络出现拥塞时,TCP的拥塞控制机制会抑制发送进程(客户或服务器)
2. UDP服务
  • UDP是一种不提供不必要服务的轻量级运输协议,它仅提供最小服务
  • UDP是无连接的,在两个进程通信前没有握手过程
  • UDP协议提供一种不可靠数据传送服务,不保证发送进程的报文将到达接收进程,且到达接收进程的报文也可能是乱序到达的
  • UDP没有包括拥塞控制机制
3. 因特网运输协议所不提供的服务
  • 目前的因特网运输协议并没有提供吞吐量和定时服务
  • 在这里插入图片描述

2.1.5 应用层协议

  • 应用层协议要解决的问题:
    • 如何构造进程间通信的报文
    • 这些报文中的各个字段的含义是什么
    • 进程何时发送这些报文
  • 应用层协议(application-layer protocol)定义了运行在不同端系统上的应用程序进程如何相互传递报文。特别是应用层协议定义了:
    • 交换的报文类型,例如请求报文和响应报文
    • 各种报文类型的语法,如报文中的各个字段及这些字段是如何描述的
    • 字段的语义,即这些字段中的信息的含义
    • 确定一个进程何时以及如何发送报文,对报文进行响应的规则
  • 区分网络应用和应用层协议:应用层协议只是网络应用的一部分

2.1.6 本书涉及的网络应用

在本章中我们详细讨论5种重要的应用:Web、文件传输、电子邮件、目录服务、流式视频和P2P

2.2 Web和HTTP

2.2.1 HTTP概况

  • Web的应用层协议是超文本传输协议(Hyper Text Transfer Protocol, HTTP),它是Web的核心
  • HTTP由两个程序实现:一个客户程序和一个服务器程序
  • 客户程序和服务器程序运行在不同的端系统中,通过交换HTTP报文进行会话。
  • HTTP定义了这些报文的结构以及客户和服务器进行报文交换的方式
  • 首先当回顾一些Web术语:
    • Web页面(Web page)(也叫文档)是由对象组成的
    • 一个对象(object)只是一个文件,诸如一个HTML文件、一个JPEG图形、一个Java小程序或一个视频片段这样的文件,且它们可通过一个URL地址寻址
    • 多数Web页面含有一个HTML基本文件(base HTML file)以及几个引用对象
    • 每个URL地址由两部分组成:存放对象的服务器主机名和对象的路径名
    • Web 浏览器(Web browser)实现 了 HTTP 的客户端,所以在Web环境中我们经常交替使用“浏览器”和“客户”这两个术语
    • Web服务器(Web server)实现了 HTTP的服务器端,它用于存储Web对象,每个对象由URL寻址
  • 在这里插入图片描述
  • 如图2-6所示,当用户请求一个Web页面(如点击一个超链接)时,浏览器向服务器发出对该页面中所包含对象的HTTP请求报文,服务器接收到请求并用包含这些对象的HTTP响应报文进行响应。
  • HTTP使用TCP作为它的支撑运输协议(而不是在UDP上运行)。
  • HTTP客户首先发起一个与服务器的TCP连接
  • 一旦连接建立,该浏览器和服务器进程就可以通过套接字接口访问TCP
  • 注意到下列现象很重要:服务器向客户发送被请求的文件,而不存储任何关于该客户的状态信息
  • HTTP服务器并不保存关于客户的任何信息,所以我们说HTTP是一个无状态协议(stateless protocol)
  • Web服务器总是打开的,具有一个固定的IP地址

2.2.2 非持续连接和持续连接

在许多因特网应用程序中,客户和服务器在一个相当长的时间范围内通信,其中客户发出一系列请求并且服务器对每个请求进行响应。依据应用程序以及该应用程序的使用方式,这一系列请求可以以规则的间隔周期性地或者间断性地一个接一个发出。

  • 当这种客户-服务器的交互是经TCP进行的,应用程序的研制者就需要做一个重要决定:该应用程序使用持续还是非持续连接?
  • 非持续连接(non-persistent connection):每个请求/响应对是经一个单独的TCP连接发送
  • 持续连接(persistent connection) :所有的请求及其响应经相同的TCP连接发送
  • HTTP既能够使用非持续连接,也能够使用持续连接
  • HTTP在其默认方式下使用持续连接
1. 采用非持续连接的HTTP
  • 在非持续连接情况下,从服务器向客户传送一个Web页面的步骤
  • 假设该页面含有一个HTML基本文件和10个JPEG图形,并且这11个对象位于同一台服务器上
  • 假设该 HTML 文件的 URL 为:http://www.someSchool.edu/someDepartment/home.index
    • 1.HTTP客户进程在端口号80发起一个到服务器www.someSchool.edu的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连接。
  • 客户能够配置现代浏览器来控制连接的并行度来获得这10个JPEG图形对象,即使用多个并行的TCP而非11个串行的TCP连接。在默认方式下,大部分浏览器打开5 ~ 10个并行的TCP连接,每条连接处理一个请求响应事务
  • 往返时间(Round-Trip Time, RTT):指一个短分组从客户到服务器然后再返回客户所花费的时间。RTT包括分组传播时延、分组在中间路由器和交换机上的排队时延以及分组处理时延
  • 在这里插入图片描述
  • 如图2-7所示,浏览器在它和Web服务器之间发起一个TCP连接,涉及一次“三次握手”过程,即客户向服务器发送一个小TCP报文段,服务器用一个小TCP报文段做出确认和响应,最后,客户向服务器返回确认
  • 三次握手中前两个部分所耗费的时间占用了一个RTT
  • 完成了三次握手的前两个部分后,客户结合三次握手的第三部分(确认)向该TCP连接发送一个HTTP请求报文
  • 该请求报文到达服务器,服务器就在该TCP连接上发送HTML文件,该HTTP请求/响应用去了另一个RTT
  • 因此,粗略地讲,总的响应时间就是两个RTT加上服务器传输HTML文件的时间
2. 采用持续连接的HTTP
  • 非持续连接有一些缺点:
    • 1.必须为每一个请求的对象建立和维护一个全新的连接。对于每个这样的连接,在客户和服务器中都要分配TCP的缓冲区和保持TCP变量,这给Web服务器带来了严重的负担,
    • 2.每一个对象经受两倍RTT的交付时延,即一个RTT用于创建TCP,另一个RTT用于请求和接收一个对象
  • 采用HTTP持续连接的情况下,服务器在发送响应后保持该TCP连接打开,在相同的客户与服务器之间,后续的请求和响应报文能够通过相同的连接进行传送
  • 一个完整的Web页面(上例中的HTML基本文件加上10个图形)可以用单个持续TCP连接进行传送,对对象的这些请求可以一个接一个地发出,而不必等待对未决请求(流水线)的回答
  • 甚至,当位于同一台服务器的多个Web页面在从该服务器发送给同一个客户时,可以在单个持续TCP连接上进行
  • 一般来说,如果一条连接经过一定时间间隔(一个可配置的超时间隔)仍未被使用,HTTP服务器就关闭该连接

2.2.3 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	#首部行

  • 请求行(request line):含三个字段:方法字段、URL字段和HTTP版本字段
    • 方法字段:有几种不同的值:GET(使用最多,用于请求一个对象)、POST、HEAD、PUT和DELETE
  • 首部行(header line)
    • Host: www someschool.edu:指明对象所在的主机。
      • 虽然在该主机中存在一条TCP连接,知晓了主机所在位置。但是此首部行提供的信息被用于Web代理的高速缓存
    • Connection:close:不使用持续连接
    • User-agent:指明用户代理,即向服务器发送请求的浏览器的类型
      • 服务器可以有效地为不同类型的用户代理发送相同对象的不同版本
    • Accept-language:用户期望接受到的报文语言版本
  • 图2-8为请求报文的通用格式
  • 在这里插入图片描述
  • 在使用POST方法时会使用到实体体(entity body)
  • 用户提交表单时(例如用户向搜索引擎提供搜索关键字时),HTTP客户常使用POST方法。当使用POST方法时,实体体中内容即为用户在表单字段中的输入值。
  • 用表单生成的请求报文不是必须使用POST方法
  • HTML表单经常使用GET方法,并在(表单字段中)所请求的URL中包括输入的数据。
  • 例如:www. somesite. com/animalsearch? monkeys&bananas 其中monkeys和bananas是表单字段
2.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: Tuer 18 Aug 2015 15:11:03 GMT
Content-Length: 6821
Content-Type: text/html
(data data data data data •••)
  • 这个响应报文包含三部分:状态行(status line)首部行(header line)实体体(entity body)
  • 实体体:报文的主要部分,包含了所请求的对象本身
  • 状态行:含三个字段:协议版本字段、状态码和相应状态信息
  • 首部行:
    • Connection: close:使用非持续连接(即发送完成后关闭该TCP连接)
    • Date:服务器产生并发送该响应报文的日期和时间
    • Server:指明产生响应的服务器类型
    • Last-Modified: 指示了所请求对象创建或者最后修改的日期和时间
    • Content-Length:被发送对象中的字节数
    • Content-Type:对象类型
  • 图2-9为响应报文的通用格式:
  • 在这里插入图片描述
  • 状态码及其相应的短语指示了请求的结果。一些常见的状态码和相关的短语包括:
    • 200 0K:请求成功,信息在返回的响应报文中
    • 301 Moved Permanently:请求的对象已经被永久转移了,新的URL定义在响应报文的Location:首部行中。客户软件将自动获取新的URL。
    • 400 Bad Request: 一个通用差错代码,指示该请求不能被服务器理解。
    • 404 Not Found:被请求的文档不在服务器上。
    • 505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本。
使用telnet查看响应报文
  • 勾选下图红框中的内容,启用telnet服务
    在这里插入图片描述
  • win+R打开cmd
  • 输入如下代码:
telnet baidu.com 80
  • 进入如下界面
    在这里插入图片描述
  • 按下Ctrl+]进入如下界面:
  • 在这里插入图片描述
  • 按下Enter进入输入界面,输入HTTP请求报文:
GET /index.php HTTP/1.1
Host:www.baidu.com
  • 连按两下Enter即可得到HTTP响应报文,见下图
  • 在这里插入图片描述

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

  • HTTP服务器是无状态的,简化了服务器的设计
  • Web站点通常希望能够识别用户,或者将内容与用户身份联系起来
  • 因此HTTP使用了cookie,它允许站点对用户进行跟踪
  • 在这里插入图片描述
  • 如图2-10所示cookie技术含四个组件:
    • 1 在HTTP响应报文中的一个cookie首部行
    • 2 在HTTP请求报文中的一个cookie首部行
    • 3 在用户端系统中保留有一个cookie文件,并由用户的浏览器进行管理
    • 4 位于Web站点的一个后端数据库

流程:假设bb使用PC通过IE浏览器上网,并首次访问Amazon.com。假定bb已经访问过eBay站点。当请求报文到达该Amazon Web服务器时,该Web站点将产生一个唯一识别码,并以此作为索引在它的后端数据库中产生一个表项。
接下来Amazon Web服务器用一个包含Set-cookie:首部的HTTP响应报文对bb的浏览器进行响应,其中Set-cookie:首部含有该识别码。例如,该首部行可能是Set-cookie:1678
当bb的浏览器收到了该HTTP响应报文时,它会看到该Set-cookie:首部。该浏览器在它管理的特定cookie文件中添加一行,该行包含服务器的主机名和在Set-cookie:首部中的识别码。值得注意的是该cookie文件已经有了用于eBay的表项,因为bb过去访问过该站点。当bb继续浏览Amazon网站时,每请求一个Web页面,其浏览器就会查询该cookie文件并抽取她对这个网站的识别码,并放到HTTP请求报文中包括识别码的cookie首部行中。特别是,发往该Amazon服务器的每个HTTP请求报文都包括以下首部行:Cookie:1678
在这种方式下,Amazon服务器可以跟踪bb在Amazon站点的活动。尽管AmazonWeb站点不必知道bb的名字,但它确切地知道用户1678按照什么顺序、在什么时间、访问了哪些页面! Amazon使用cookie来提供它的购物车服务,即Amazon能够维护bb希望购买的物品列表,这样在bb结束会话时可以一起为它们付费。
如果bb再次访问Amazon站点,比如说一个星期后,她的浏览器会在其请求报文中继续放入首部行cookie: 1678。Amazon将根据bb过去在Amazon访问的网页向他推荐产品。

  • cookie用于标识一个用户,因而cookie可以在无状态的HTTP之上建立一个用户会话层

2.2.5 Web缓存

  • Web缓存器(Web cache)又叫代理服务器(proxy server):用于代表初始Web服务器满足HTTP请求的网络实体。
  • Web缓存器有自己的磁盘存储空间,存储空间中保存最近请求过的对象的副本。
  • 如图2-11所示,可以配置用户的浏览器,使得用户的所有HTTP请求首先指向Web缓存器
  • 在这里插入图片描述

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

  • 部署Web缓存器的两个原因:
    • 1 Web缓存器可以大大减少对客户请求的响应时间
    • 2 Web缓存器能够大大减少一个机构的接入链路到因特网的通信量。通过减少通信量,该机构就不必急于增加带宽,因此降低了费用
    • 此外,Web缓存器能从整体上大大减低因特网上的Web流量,从而改善了所有应用的性能。
  • 通过使用内容分发网络(Content Distribution Network,CDN),Web缓存器正在因特网中发挥着越来越重要的作用

2.2.6 条件GET方法

Web缓存器可以提升响应时间,但是缓存其中的副本有可能是陈旧的

  • HTTP采用**条件GET(conditional GET)**方法,允许缓存器证实它的对象是最新的
    • 条件:1 请求报文使用GET方法
    • 2 请求报文中包含一个“If-Modified-Since:”首部行,则这个HTTP请求为一个条件GET请求报文
  • 看一个例子:
    • 首先某浏览器向Web服务器发送一个请求
GET /fruit/kiwi・gif HTTP/1.1
Host: www.exotiquecuisine.com
  • 然后该Web服务器向缓存器发送被请求的响应报文
HTTP/1.1 200 OK
Date Sat, 3 Oct 2015 15:39:29
Server: Apache/1.3.0 (Unix)
Last-Modified: Wed, 9 Sep 2015 09:23:24
Content-Type image/gif
(data data data data data ...)
  • 缓存器在将对象转发到请求的浏览器的同时,也在本地缓存了该对象。同时也存储了该对象的最后修改时间
  • 一周后,另一个用户经过该缓存器请求同一个对象,该对象仍在这个缓存器中。为判断该对象是否在过去的一周被修改,缓存器向Web服务器发送一个条件GET进行检查:
 GET /fruit/kiwi.gif HTTP/1.1
 Host www.exotiquecuisine.com
 If-modified-since Wed, 9 Sep 2015 09:23:24 #为一周前服务器响应报文中Last-Modified:首部行的值
  • 仅当自指定日期之后该对象被修改过,才发送该对象
  • 若未被修改则Web服务器响应报文如下:
HTTP/1.1 304 Not Modified #告诉缓存器可以使用该对象
Date Sat, 10 Oct 2015 15:39:29
Server Apache/1.3.0 (Unix)
(empty entity body)

2.3 因特网中的电子邮件

  • 图2-14给出了因特网电子邮件系统的总体情况。
  • 在这里插入图片描述
  • 包含三个组成部分:用户代理(user agent)邮件服务器(mail server)简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)
    • 用户代理允许用户阅读、回复、转发、保存和撰写报文
    • 当发送方完成邮件撰写后,其邮件代理向其邮件服务器发送邮件,此时邮件放在邮件服务器的外出报文队列中
    • 当接收方要读邮件时,其用户代理在其邮件服务器的邮箱中获取邮件
  • 每个接收方在某个邮件服务器上有一个邮箱(mailbox)
  • 一个典型的邮件发送过程:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后在这里被分发到接收方的邮箱中。当接收方在其邮箱中读取邮件时,包含他邮箱的邮件服务器(使用用户名和口令)来鉴别接收方。发送方的邮箱也必须能处理接收方的邮件服务器故障。当发送方的服务器不能将邮件交付给接收方的服务器,发送方的邮件服务器在一个**报文队列(message queue)**中保持该报文并在以后尝试再次发送。如果几天后仍不能成功,服务器就删除该报文并以电子邮件的形式通知发送方。
  • SMTP是因特网电子邮件中主要的应用层协议
  • SMTP使用TCP传输服务
  • SMTP也有客户端和服务器端,每台邮件服务器既是客户端也是服务器端

2.3.1 SMTP

  • SMTP一般不使用中间邮件服务器发送邮件,即使这两个邮件服务器位于地球的两端也是这样
  • 即使接收方的邮件服务器没有开机,该报文会保留在发送方的邮件服务器上,并等待新的尝试,而不会在中间的某个邮件服务器存留。
  • 在SMTP握手的阶段(TCP建立连接之后),SMTP客户指示发送方的邮件地址(产生报文的那个人)和接收方的邮件地址。
  • SMTP握手之后,客户发送报文
  • SMTP借助TCP实现无差错传输服务,若还有报文需要传送至该服务器,使用相同的TCP连接即可,否则TCP连接关闭。
  • 使用25号端口
  • SMTP使用持续连接
  • 一个例子,C为客户,主机名为crepes.fr;S为服务器,主机名为hamburger.edu。C开头的ASCII为客户交给TCP套接字的,S开头的ASCII为服务器交给TCP套接字的。
  • 在这里插入图片描述
  • 上例中,客户发送了五条指令:HELO(HELLO缩写)、MAIL FROM、RCPT TO、DATA和QUIT
使用telnet用SMTP给他人发邮件教程(亲测好用)

2.3.2 与HTTP对比

  • 相同点:
    • 这两个协议都用于从一台主机向另一台主机传送文件
    • 当进行文件传送时,持续的HTTP和SMTP都使用持续连接
  • 不同点1
    • HTTP主要是一个拉协议(pull protocol):即在方便的时候,某些人在Web服务器上装载信息,用户使用HTTP从该服务器拉取这些信息。特别是TCP连接是由想接收文件的机器发起的
    • SMTP基本上是一个推协议(push protocol):发送邮件服务器把文件推向接收邮件服务器。特别是,这个TCP连接是由要发送该文件的机器发起的。
  • 不同点2
    • SMTP要求每个报(包括它们的体)采用7比特ASCII码格式。如果某报文包含了非7比特ASCII字符或二进制数据(如图形文件),则该报文必须按照7比特ASCII码进行编码。
    • HTTP数据不受这种限制
  • 不同点3:如何处理一个既包含文本又包含图形(也可能是其他媒体类型)的文档
    • HTTP把每个对象封装到它自己的HTTP响应报文中
    • SMTP则把所有报文对象放在一个报文之中

2.3.3 邮件报文格式

  • 发送电子邮件时,一个包含环境信息的首部位于报文体前面,这些环境信息包括在一系列首部行中
  • 首部行和报文体用空行进行分隔
  • 每个首部必须包含一个From:首部行和一个To:首部行
  • 注意:这里的首部行与2.3.1SMTP命令不一样。SMTP命令是握手协议的一部分,本节这些首部行是邮件报文自身的一部分
  • 在报文首部后,紧接一个空白行,然后就是ASCII格式的报文体

2.3.4 邮件访问协议

  • 过去接收方通过登录到服务器主机,并直接在该主机上运行一个邮件阅读程序来阅读邮件
  • 如今,邮件访问使用客户-服务器体系结构:用户通过在用户端系统上运行的客户程序来阅读电子邮件
  • 发送方发送邮件的时候需要分两步:发送方的用户代理将邮件推入发送方的邮件服务器,然后发送方的邮件服务器将邮件发送给接收方的邮件服务器。原因是:不经过发送方的邮件服务器进行中继,发送方的用户代理没法发到达不可达(例如接收方的邮件服务器宕机了,这时需要发送方的邮件服务器每隔30min发送一次,直到接收方的邮件服务器正常接受为止)的目的地接受服务器
  • 接收方的用户代理不能使用SMTP读取报文,读取报文是拉取操作,SMTP是推协议
  • 目前流行的一些邮件访问协议:第三版的邮局协议(Post Office Protocol—Version 3 , POP3)因特网邮件访问协议(Internet Mail Access Protocol,IMAP)HTTP
  • 如图2-16为因特网邮件的一些协议:推和拉
  • 在这里插入图片描述
1. POP3
  • 当用户代理(客户)打开了一个到邮件服务器110号端口的TCP连接后,POP3开始工作
  • POP3按照三个阶段进行工作:特许(authorization)、事务处理以及更新
    • 特许阶段:用户代理发送(以明文形式)用户名和口令以鉴别用户
    • 事务处理阶段:用户代理取回报文,同时还可以在这个阶段执行以下操作:对报文做删除标记、取消报文删除标记和获取邮件的统计信息
    • 更新阶段:出现在客户发出了 quit命令之后,目的是结束该POP3会话;这时,邮件服务器删除那些被标记为删除的报文
  • 在POP3的事务处理过程中,用户代理发出一些命令,服务器对每个命令做出回答。回答指令有两种
    • +OK(有时后面还跟有服务器到客户的数据),被服务器用来指示前面的命令是正常的
    • -ERR,被服务器用来指示前面的命令出现了某些差错
  • 特许阶段两个命令:user < user name >和pass < password >
  • 使用POP3的用户代理通常被用户配置为“下载并删除”或者“下载并保留”方式
    • 下载并删除方式:用户代理发出list、retr和dele命令
    • list:用户代理首先请求邮件服务器列出所有存储的报文的长度
    • retr:用户代理从邮件服务器取回邮件
    • del:用户代理从邮件服务器删除邮件
    • quit:执行此命令后,POP3进入更新阶段,删除邮件
使用telnet来感受POP3

步骤如下:

  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述
2. IMAP
  • 移动用户喜欢使用一个在远程服务器上的层次文件夹实现删除报文、在文件夹之间移动报文和查询报文的操作,这样他可以从任何一台机器上对所有报文进行访问。POP3没有给用户提供这样的服务
  • IMAP是一个邮件访问协议,它比POP3具有更多的特色,也比POP3复杂得多。
  • 1MAP服务器把每个报文与一个文件夹联系起来;当报文第一次到达服务器时,它与收件人的INBOX文件夹相关联。
  • 收件人则能够把邮件移到一个新的、用户创建的文件夹中,阅读邮件,删除邮件等。
  • IMAP协议为用户提供了创建文件夹以及将邮件从一个文件夹移动到另一个文件夹的命令
  • IMAP为用户提供了在远程文件夹中查询邮件的命令,按指定条件去查询匹配的邮件
  • IMAP服务器维护了 IMAP会话的用户状态信息(POP3不维护),例如,文件夹的名字以及哪些报文与哪些文件夹相关联。
  • IMAP的另一个重要特性是它具有允许用户代理获取报文某些部分的命令
3. 基于Web的电子邮件
  • 使用基于Web的电子邮件服务,用户代理就是普通的浏览器,用户和他远程邮箱之间的通信则通过HTTP进行
  • 发送和接受电子邮件均使用HTTP协议实现用户代理和服务器之间的交互
  • 而邮件服务器之间的收发邮件仍然使用SMTP

2.4 DNS:因特网的目录服务

因特网上的主机和人类一样,可以使用多种方式进行标识。
主机的一种标识方法是用它的主机名 (hostname), 如 www.baidu.com、www.bing.com等
这些名字便于记忆也乐于被人们接受
然而,主机名几乎没有提供(即使有也很少)关于主机在因特网中位置的信息
主机名可能由不定长的字母数字组成,路由器难以处理
基于这些原因,主机也可以使用**IP地址(IP address)**进行标识

简要介绍一下IP地址,第四章会进行更为详细的讨论
一个IP地址由4个字节组成,并有着严格的层次结构,例如121.7.106. 83
一个IP地址,其中的每个字节都被句点分隔开来,表示了 0~255的十进制数字。

2.4.1 DNS提供的服务

  • 识别主机有两种方式,通过主机名或者IP地址
  • 人们喜欢便于记忆的主机名标识方式
  • 路由器则喜欢定长的、有着层次结构的IP地址
  • 为了折中这些不同的偏好,我们需要一种能进行主机名到IP地址转换的目录服务,即:域名系统(Domain Name System, DNS)
  • DNS是:
    • 一个由分层的**DNS服务器(DNSserver)**实现的分布式数据库
    • 一个使得主机能够查询分布式数据库的应用层协议
    • DNS 服务器通常是运行 BIND ( Berkeley Internet Name Domain)软件的UNIX机器。DNS协议运行在UDP之上,使用53号端口。
  • DNS协议是应用层协议,不直接和用户打交道。DNS是为因特网上的用户应用程序以及其他软件提供一种核心功能:将主机名转换为IP地址
  • DNS执行过程(某用户通过浏览器访问www.baidu.com/index.html):
    • 为使用户浏览器能将报文发送到百度服务器,需要知道其IP地址
    • 1 该用户主机上运行着DNS客户端
    • 2 浏览器从上述URL中抽取出主机名www.baidu.com,并将其发送给DNS客户端
    • 3 DNS客户端向DNS服务器发送包含主机名的请求
    • 4 DNS服务器响应该请求,将该主机名的IP地址发送回去
    • 5 浏览器得知目标服务器的IP地址后,向位于该IP地址80号端口的HTTP服务器进程发起一个TCP连接
  • DNS给使用它的因特网应用带来了额外的时延,幸运的是想获得的IP地址通常就缓存在一个附近的” DNS服务器中,这有助于减少DNS的网络流量和DNS的平均时延
  • DNS还提供的一些重要的服务:
    • 主机别名(host aliasing):有着复杂主机名的主机能拥有一个或者多个别名。例一台名为relay1. west-coast.enterprise.com的主机,可能还有两个别名为enter-prise.com 和 www. enterprise. com。此时relay1. west-coast.enterprise.com称为规范主机名(canonical hostname)。应用程序可以调用DNS来获得主机别名对应的规范主机名以及主机的IP地址。
    • 邮件服务器别名(mail server aliasing):人们非常希望电子邮件地址好记忆。电子邮件应用程序可以调用DNS,对提供的主机名别名进行解析,以获得该主机的规范主机名及其IP地址。MX记录(参见后面)允许一个公司的邮件服务器和Web服务器使用相同(别名化的)的主机名
    • 负载分配(load distribution):DNS也用于在冗余的服务器之间进行负载分配。繁忙的站点被冗余分布在多台服务器上,每台服务器均运行在不同的端系统上,每个都有着不同的IP地址。因此需要一个IP地址集合将这些Web服务器的IP地址与同一个主机名相联系。DNS数据库中存储着这些IP地址集合。当客户对映射到某地址集合的名字发出一个DNS请求时,该服务器用IP地址的整个集合进行响应,但在每个回答中循环这些地址次序(循环地址次序即为DNS的负载分配)。因为客户通常总是向IP地址排在最前面的服务器发送HTTP请求报文。

2.4.2 DNS工作机理概述

DNS采用了分布式的设计方案,是一个在因特网上实现分布式数据库的精彩范例。

1.分布式、层次数据库
  • 为了处理扩展性问题,DNS使用了大量的DNS服务器,它们以层次方式组织,并且分布在全世界范围内。
  • 有3种类型的DNS服务器:根DNS服务器、顶级域(Top-Level Domain, TLD) DNS服务器和权威DNS服务器。如图2-17所示为这些服务器的组织结构
  • 在这里插入图片描述
  • 用户访问过程:先访问根,根返回TLD的;然后访问TLD,TLD返回权威DNS服务器;最后访问权威DNS服务器,权威DNS服务器返回访问服务器的IP地址
    • 根DNS服务器:有400多个根名字服务器遍及全世界,由13个不同的组织管理。根名字服务器提供TLD服务器的IP地址。
    • 顶级域(DNS)服务器:对于每个顶级域(如com、org、net、edu和gov)和所有国家的顶级域(如uk、fr、ca和jp),都有TLD服务器(或服务器集群)。TLD服务器提供了权威DNS服务器的IP地址。
    • 权威DNS服务器:在因特网上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织机构必须提供公共可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。一个组织机构的权威DNS服务器收藏了这些DNS记录或支付费用让这些记录存储在某个服务提供商的一个权威DNS服务器中。
  • 本地DNS服务器(local DNS server):本地DNS服务器并不属于图2-17所述服务器的层次结构
  • 每个ISP (如一个居民区的1SP或一个机构的ISP)都有一台本地DNS服务器(也叫默认名字服务器)
  • 通常通过DHCP(将在第四章介绍)用户主机在接入某ISP后可以访问到一台或多台其本地DNS服务器的IP地址
  • 看一个例子:在这里插入图片描述
    • 1 用户向其本地DNS服务器发送DNS查询报文
    • 2 本地DNS服务器将其转发到根DNS服务器
    • 3 根DNS服务器发现edu后缀,则将edu的TLD服务器IP返回给本地DNS服务器
    • 4 本地DNS服务器向TLD服务器发送查询报文
    • 5 TLD服务器发现umass.edu后缀,则将权威DNS服务器的IP返回给本地DNS服务器
    • 6 本地服务器向权威DNS服务器发送查询报文
    • 7 权威DNS服务器返回gaia.cs.umass.edu的IP地址
    • 8 本地DNS服务器向用户返回查询到的IP地址
  • 图2-18案例使用到了递归查询(recursive query)迭代查询(iterative query)
2.DNS缓存

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

  • 缓存原理:当某个DNS服务器接收到一个DNS回答(其中包含某主机名到其IP地址的映射),该DNS服务器就将这个映射缓存在本地存储器中。当再次查询到这个主机/IP地址对时,就可以直接提供所求的IP地址。
  • 由于主机和主机名与IP地址间的映射并不是永久的,DNS服务器在一段时间后(通常设置为两天)将丢弃缓存的信息。
  • 本地DNS服务器也能够缓存TLD服务器的IP地址,因而允许本地DNS绕过查询链中的根DNS服务器。

2.4.3 DNS记录和报文

DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record,RR),RR提供了主机名到IP地址的映射

  • 资源记录是一个包含了下列字段的4元组:(Name,Valuer,Type,TTL)
    • TTL:表示该记录的生存时间,它决定了资源记录应当从缓存中删除的时间
    • Name和Value的值取决于Type
      • 如果Type = A,Name是主机名,Value是该主机名对应的IP地址
      • 如果Type = NS,则Name是个域(如foo.com),而Value是个知道如何获得该域中主机IP地址的权威DNS服务器的主机名这个记录用于沿着查询链来路由DNS查询
      • 如果Type二CNAME,贝lj Value是别名为Name的主机对应的规范主机名。该记录能够向査询的主机提供一个主机名对应的规范主机名
      • 如果Type = MX,则Value是个别名为Name的邮件服务器的规范主机名。MX记录允许邮件服务器主机名具有简单的别名。值得注意的是,通过使用MX记录,一个公司的邮件服务器和其他服务器(如它的Web服务器)可以使用相同的别名。
      • 为了获得邮件服务器的规范主机名,DNS客户应当请求一条MX记录;而为了获得其他服务器的规范主机名,DNS客户应当请求CNAME记录。
1. DNS报文

DNS只有查询和回答报文,并且,查询和回答报文有着相同的格式

  • 图2-20所示为DNS报文中各字段的语义
  • 在这里插入图片描述
  • 前12个字节是首部区域。
    • 第一个字段(标识符)是一个16比特的数,用于标识该查询。这个标识符会被复制到对查询的回答报文中,以便让客户用它来匹配发送的请求和接收到的回答。
    • 标志字段中含有若干标志。1比特的“查询/回答”标志位指出报文是查询报文(0)还是回答报文(1)
    • 当某DNS服务器是所请求名字的权威DNS服务器时,1 比特的“权威的”标志位被置在回答报文中。
    • 如果客户(主机或者DNS服务器)在该DNS服务器没有某记录时希望它执行递归查询,将设置1比特的“希望递归”标志位。如果该DNS服务器支持 递归查询,在它的回答报文中会对1 比特的“递归可用”标志位置位。
    • 在该首部中,还有4个有关数量的字段,这些字段指出了在首部后的4类数据区域出现的数量。
  • 问题区域包含着正在进行的查询信息。
    • 名字字段:包含正在被查询 的主机名字
    • 类型字段:指出有关该名字的正被询问的问题类型,例如主机地址是与一个名字相关联(类型A)还是与某个名字的邮件服务器相关联(类型MX)。
  • 回答区域包含了对最初请求的名字的资源记录
    • 每个资源记录中有Type (如A、NS、CNAME和MX)字段、Value字段和TTL字段。
    • 在回答报文的回答区域中可以包含多条RR,因此一个主机名能够有多个IP地址(例如,就像本节前面讨论的冗余Web服务器)。
  • 权威区域包含了其他权威服务器的记录。
  • 附加区域包含了其他有帮助的记录。
nslookup向DNS服务器发送查询报文步骤
2. 在DNS数据库中插入记录

上面讨论的是从DNS数据库中取数据,现在来看看这些数据是如何存入数据库中的

  • 一个例子:
  • 假定你刚刚创建一个称为网络乌托邦(Network Utopia)的令人兴奋的新创业公司。
  • 你必定要做的第一件事是 在注册登记机构注册域名networkutopia. como 注册登记机构(registrar)是一个商业实体, 它验证该域名的唯一性,将该域名输入DNS数据库(如下面所讨论的那样),对提供的服 务收取少量费用。
  • 当你向某些注册登记机构注册域名networkutopia, com时,需要向该机构提供你的基本和辅助权威DNS服务器的名字和IP地址。
  • 假定该名字和1P地址是dnsl. networkutopia.com 和 dns2.networkutopia.com 及 212. 212. 212. 1 和 212. 212. 212. 2。
  • 对这两个权威 DNS 服务器的每一个,该注册登记机构确保将一个类型NS和一个类型A的记录输入TLD com服务 益。特别是对于用于networkutopia, com的基本权威服务器,该注册登记机构将下列两条资 源记录插入该DNS系统中:
  • (networkutopia.corn, dnsl.networkutopia.com, NS) (dnsl.networkutopia.com. 212.212.212.1, A)
  • 你还必须确保用于Web服务器www. networkutopia.com的类型A资源记录和用于邮件 服务器mail.networkutopia.com的类型MX资源记录被输入你的权威DNS服务器中。
  • 一旦完成所有这些步骤,人们将能够访问你的Web站点,并向你公司的雇员发送电子邮件。

2.5 P2P文件分发

使用客户-服务器体系结构,对于基础设施服务器的依赖过大。使用P2P体系结构,对基础设施服务器有最小的(或者没有)依赖。

1.P2P体系结构的扩展性

考虑一个用于客户-服务器体系结构和P2P体系结构的简单定量模型:将一个文件分发个一个固定的对等方集合。如图2-21所示

  • 在这里插入图片描述

  • u s u_s us:服务器接入链路的上载速率

  • u i u_i ui:第i个对等方接入链路的上载速率

  • d i d_i di:第i个对等方接入链路的下载速率

  • F F F:被分发的文件长度(以比特记)

  • N N N:要获得该文件副本的对等方的数量

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

  • 假设:1 因特网核心具有足够的带宽,所有的瓶颈都在网络接入链路;2 服务器和客户没有参与任何其他网络应用,它们的所有上传和下载访问带宽能全部用于分发该文件

  • D c s D_{cs} Dcs:客户-服务器体系结构的分发时间

    • 服务器必须向每一个对等方传输一个文件副本,因此服务器必须传输 N F NF NF比特,服务器上载速率为 u s u_s us,则分发文件的时间至少为: N F / u s NF/u_s NF/us
    • d m i n d_{min} dmin:对等方的最小下载速率, d m i n = m i n { d 1 , d p , . . . , d N } d_{min} = min\{d_1,d_p,...,d_N\} dmin=min{d1,dp,...,dN}。因此最小分发时间至少为 F / d m i n F/d_{min} F/dmin
    • 讲二者放在一起看,有: D c s ≥ m a x { N F / u s , F / d m i n } D_{cs} ≥ max\{NF/u_s, F/d_{min}\} Dcsmax{NF/us,F/dmin},这个是客户-服务器模式最小分发时间的下届
    • 当N很大时,分发时间由 N F / u s NF/u_s NF/us确定
  • D P 2 P D_{P2P} DP2P:每个对等方能够帮助服务器分发该文件。特别是,当一个对等方接收到某些文件数据,它能够使用自己的上载能力重新将数据分发给其他对等方。计算起来比较复杂

    • 分发开始时,只有服务器具有文件。所以服务器必须经其接入链路至少发送该文件的每个比特一次,因此最小分发时间至少为 F / u F/u F/u
    • d m i n d_{min} dmin:对等方的最小下载速率, d m i n = m i n { d 1 , d p , . . . , d N } d_{min} = min\{d_1,d_p,...,d_N\} dmin=min{d1,dp,...,dN}。因此最小分发时间至少为 F / d m i n F/d_{min} F/dmin
    • 系统整体的上载能力等于服务器的上载速率加上每个单独的对等方的上载速率,即 u t o t a l = u s + u 1 + . . . + u N u_{total} = u_s+u_1+...+u_N utotal=us+u1+...+uN。系统必须向这N个对等方的每个交付(上载)F比特,因此总共交付NF比特。最大速率为 u t o t a l u_{total} utotal,因此最小的分发时间为: N F / ( u s + u 1 + . . . + u N ) NF/(u_s+u_1+...+u_N) NF/(us+u1+...+uN)
    • 将上述三个观察放在一起,得到P2P的最小分发时间: D P 2 P ≥ m a x { F / u s , F / d m i n , N F / ( u s + ∑ i = 1 n u i ) } D_{P2P}≥max\{F/u_s,F/d_{min},NF/(u_s+\sum_{i=1}^{n}u_i)\} DP2Pmax{F/us,F/dmin,NF/(us+i=1nui)}(最小分发时间下界)
  • 图2-22为客户=服务器和P2P体系结构的最小分发时间

  • 在这里插入图片描述

  • 对于客户-服务器体系结构,随着对等方数量的增加,分发时间呈线性增长并且没有上界

  • 对于P2P体系结构,最小分发时间不仅总是小于客户-服务器体系结构的分发时间,并且对于任意的对等方数量N,总是小于1小时(假定 F / u = 1 小 时 F/u=1小时 F/u=1

具有P2P体系结构的应用程序能够是自扩展的。这种扩展性的直接成因是:对等方除了是比特的消费者外还是它们的重新分发者

2.BitTorrent
  • BitTorrent是一种用于文件分发的流行P2P协议
  • 参与一个特定文件分发的所有对等方的集合被称为一个洪流(torrent)
  • 在一个洪流中的对等方彼此下载等长度的文件块(chunk),典型的块长度为256KB
  • 当一个对等方首次加入一个洪流时,它一个块都没有。随着时间的流失,该对等方收集了越来越多的块,同时为其他对等方上载了多个块
  • 一旦某对等方获得了整个文件,它可以选择离开该洪流,也可以选择继续留在此洪流中向其他对等方上载块
  • 任何对等方可能在任何时候仅具有块的子集就离开洪流,并在以后重新加入洪流
  • 仔细查看BitTorrent协议:
    • 追踪器(tracker):每个洪流具有一个基础设施节点
    • 当一个对等方加入某洪流时,它向追踪器注册自己,并周期性地通知追踪器它仍在该洪流中
    • 以这样的方式,追踪器跟踪参与在洪流中的对等方
    • 如图2-23所示:
    • 在这里插入图片描述
    • 当一个新的对等方Alice加入该洪流时,追踪器随机地从参与对等方的集合中选择对等方的一个子集(假设含有50个对等方),并将这50个对等方的IP地址发送给Alice
    • Alice持有对等方的这张列表,试图与该列表上的所有对等方创建并行的TCP连接
    • 将所有这样与Alice成功地创建一个TCP连接的对等方称为“邻近对等方”
    • 随着时间的流逝,这些对等方中的某些可能离开,其他对等方(最初50个以外的)可能试图与Alice创建TCP连接。因此一个对等方的邻近对等方将随时间而波动。
    • 在任何给定的时间,每个对等方将具有来自该文件的块的子集,并且不同的对等方具有不同的子集
    • Alice周期性地(经TCP连接)询问每个邻近对等方它们所具有的块列表,有了这个信息,Alice将对她当前还没有的块发出请求(仍通过TCP连接)。
    • 在任何时刻,Alice具有块的子集,并且知道它的邻居有哪些块,此时Alice需要做出两个决定:
      • 1.她应当从她的邻居请求哪些块
      • 2.她应当向哪些向她请求块的邻居发送块
    • 问题1的解决采用**最稀缺优先(rarest first)**技术:最稀缺的块就是那些在她的邻居中副本数量最少的块,并首先请求那些最稀缺的块。目的是将最稀缺的块得到更为迅速的分发,从而均衡每个块在洪流中副本的数量
    • 问题2的解决使用一种对换算法:Alice根据当前能够以最高速率向她提供数据的邻居,给出其优先权。
    • Alice对于她的每个邻居都持续地测量接收到比特的速率,并确定以最高速率流入的4个邻居。每过10秒,她重新计算该速率并可能修改这4个对等方的集合
    • 这四个对等方被称为疏通(unchoked)
    • 每过30s,Alice随机选择另外一个邻居向其发送块(称为Bob)。此时Alice向Bob发送数据,则Alice有可能成为Bob的前4上载者,这样Bob将向Alice传送数据。若Bob向Alice传送数据速率较高,则下一轮Bob仍然有可能成为前四上载者。
    • 即每过30秒Alice将随机地选择一名新的对换伴侣并开始与那位伴侣进行对换。如果这两名对等方都满足此对换,它们将对方放入其前4位列表中并继续与对方进行对换,直到该对对等方都满足此对换,它们将对方放入其前4位列表中并继续与对方进行对换,直到该对等方之一发现了一个更好的伴侣为止。
    • 还有一个随机选择邻居,这样允许新的对等方得到块,这样新的节点也能有东西置换
  • 另外一种P2P应用:分布式散列表(DHT)
    • 分布式散列表是一种简单的数据库,其数据库记录分布在一个P2P系统的多个对等方上。DHT得到了广泛实现(如在BitTorrent中),并成为大量研究的主题。

2.6 视频流和内容分发网

本节将对如何在因特网中实现视频流服务进行概述
视频是一系列的图像,以一种恒定的速率来展现
一幅未压缩、数字编码的图像由像素阵列组成,其中每个像素是由一些比特编码来表示亮度和颜色
视频的一个重要特征是它能够被压缩,因而可用比特率来权衡视频质量
比特率越高,图像质量越好,用户的总体视觉感受越好

2.6.1 因特网视频

  • 在流式存储视频应用中,基础的媒体是预先录制的视频,例如电影、电视节目、录制好的体育事件或录制好的用户生成的视频
  • 这些预先录制好的视频放置在服务器上,用户按需向这些服务器发送请求来观看视频
  • 到目前为止,对流式视频的最为重要的性能度量是平均端到端吞吐量
  • 可以将同一个视频压缩成多个版本,每个版本具有不同的质量等级,用户能够根据他们当前的可用带宽决定观看哪个版本

2.6.2 HTTP流和DASH

  • 在HTTP流中,视频只是存储在HTTP服务器中作为一个普通的文件,每个文件有一个特定的URL

  • 客户要看视频时,建立与服务器的TCP连接,并发送对该URL的HTTP GET请求

  • 服务器在HTTP响应报文中发送该视频

  • 客户端,接收到的字节被收集在客户应用缓存中,当缓存字节数量超过一定的门限,就开始播放视频

  • 流式视频应用接收到视频就进行播放,同时缓存该视频后面部分的帧

  • 经HTTP的动态适应性流(Dynamic Adaptive Streaming over HTTP,DASH):视频编码为几个不同的版本,其中每个版本具有不同的比特率,对应于不同的质量水平。用户根据自己的网络状况选取不同的比特率版本的视频

  • DASH允许客户根据目前的网络状况自适应的选取对应视频的视频进行播放

  • 使用DASH后,每个视频版本存储在HTTP服务器中,每个版本都有一个不同的URL

  • 告示文件(manifest file):HTTP服务器为每个版本提供了一个URL及其比特率

  • 1 客户首先请求该告示文件并且得知各种各样的版本

  • 2 客户通过在HTTP GET请求报文中对每块指定一个URL和一个字节范围,一次选择一块

  • 3 在下载块的同时,客户也测量接收带宽并运行一个速率决定算法来选择下次请求的块(缓存视频多且带宽高,就选择一个高速率版本。缓存视频少且带宽小,就选择一个低速率版本)

2.6.3 内容分发网

为了应对向分布于全世界的用户分发巨量视频数据的挑战,几乎所有主要的视频流公司都利用内容分发网(Content Distribution Network, CDN)

  • CDN管理分布在多个地理位置上的服务器,在它的服务器中存储视频(和其他类型的Web内容,包括文档、图片和音频)的副本,并且所有试图将每个用户请求定向到一个将提供最好的用户体验的CDN位置。
  • 专用CDN (private CDN):它由内容提供商自己所拥有
  • 第三方CDN (third- party CDN):它代表多个内容提供商分发内容
  • CDN采用两种不同的服务器安置原则:
    • 1 深入:通过在遍及全球的接入ISP中部署服务器集群来深入到ISP的接入网中。其目标是靠近端用户,通过减少端用户和CDN集群之间链路和路由器的数量,从而改善用户感受到的时延和吞吐量
    • 2 邀请做客:通过在少量(例如10个)关键位置建造大集群来邀请到ISP做客
1.CDN操作
  • 当用户主机中的一个浏览器指令检索一个特定的视频(由URL标识)时,CDN必须截获该请求,以便:
    • 1.确定此时适合用于该客户的CDN服务器集群
    • 2.将客户的请求重定向到该集群的某台服务器
  • 大多数CDN利用DNS来截获和重定向请求
  • 一个例子,如图2-24所示
    • 在这里插入图片描述
    • 假定一个内容提供商NetCinema雇佣了第三方CDN公司KingCDN来向其客户分发视频
    • 1.用户访问位于NetCinema的Web网页
    • 2.当用户点击链接http://video.netcinema.com/6Y7B23V时,该用户主机发送了一个对于video.netcinema.com的DNS请求
    • 3.用户的本地DNS服务器(LDNS)将该DNS请求中继到一台用于NetCinema的权威DNS服务器,该服务器观察到主机名video.netcinema.com中包含的“video”。为了将此DNS请求移交给KingCDN,NetCinema的权威DNS服务器不返回IP地址,而是返回一个KingCDN域的主机名,例如为:a1105.kingcdn.com
    • 4.此时DNS进入到KingCDN专用DNS基础设施,用户的LDNS对a1105.kingcdn.com发送第二个请求,KingCDN的DNS系统最终向LDNS返回KingCDN内容服务器的IP地址。在这里,KingCDN的DNS系统中指定了 CDN服务器.客户将能够从这台服务器接收到它的内容。
    • 5.LDNS向用户主机转发内容服务CDN节点的IP地址。
    • 6.客户得知KingCDN服务器的IP地址,便与其建立TCP连接,并发出HTTP GET请求
2.集群选择策略
  • 任何CDN部署,其核心是集群选择策略(cluster selection strategy),即动态地将客户定向到CDN中的某个服务器集群或数据中心的机制
  • 如上例中,CDN在得知了该客户的LDNS服务器的IP后,需要基于该IP选择一个适当的集群
  • CDN —般采用专用的集群选择策略
  • 策略1:地理上最为邻近(geographically closest):每个LDNS IP地址都映射到一个地理位置,CDN选择地理上最为接近的集群。这样的策略大部分情况下work的很出色,但是对于一些客户来说,效果可能较差(网络路径的长度或跳数而言,地理最邻近的集群可能并不是最近的集群)。此外某些端用户配置的LDNS是远端的LDNS。同时,这种简单的策略忽略了时延和可用带宽随因特网路径时间而变化,总是为特定的客户指派相同的集群。
  • 策略2:**实时测量(real-time measurement) **:CDN能够让它的每个集群周期性地向位于全世界的所有LDNS发送探测分组,用以测试时延

2.6.4 学习案例:Netflix、YouTube和“看看”

感兴趣的读者可以去阅读《计算机网络-自顶向下方法》一书,此处不做赘述

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

  • 网络应用程序有两类
    • 一类是由协议标准(如一个RFC或某种其他标准文档)中所定义的操作的实现
    • 另一类网络应用程序是专用的网络应用程序

2.7.1 UDP套接字编程

  • 当使用UDP时,必须先将目的地址附在该分组之上
  • 发送进程会为分组附上目的地址,其中包含目的主机的IP地址,同时因为每个进程拥有一个或者多个套接字,当生成套接字的时候也会为其分配一个端口号(port number),此时目的地址包含端口号
  • 发送方的源主机IP地址和套接字的端口号构成源地址,其也附在分组之上
  • (将源地址附在分组之上通常并不是由UDP应用程序代码所为,而是由底层操作系统自动完成的)

使用下列简单的客户-服务器应用程序来演示对于UDP和TCP的套接字编程
1 客户从其键盘读取一行字符(数据)并将该数据向服务器发送
2 服务器接收该数据并将这些字符转换为大写
3 服务器将修改的数据发送给客户
4 客户接收修改的数据并在其监视器上将该行显示出来

  • 图2-26为客户和服务器通过UDP的主要与套接字相关的活动
  • 在这里插入图片描述
1. UDPClient.py

代码如下:

from socket import * 
# socket模块形成了在Python中所有网络通信的基础
ServerName = 'hostname' 
#两种方式,要么提供IP地址,要么提供主机名,然后使用DNS获取IP地址
serverPort = 12000
#将端口设置为12000
clientSocket = socket(AF_INET,SOCK_DGRAM)
#创建客户端的套接字,第一个参数指示地址簇,第二个参数指示套接字为UDP类型
#创建套接字时,并没有指明端口号这个过程交由操作系统完成
message = raw_input('Input lowercase sentences:')
#要发送的信息
clientSocket.sendto(message.encode(),(serverName,serverPort))
#首先将字符串类型转化为字节类型(encode函数),然后使用sendto函数为报文附上目的地址
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
#接受服务器返回来的报文分组,serverAddress包含了服务器的IP地址和服务器的端口号
print(modifiedMessage.decode())
#将报文从字节转化为字符串后打印出来
clientSocket.close()
#关闭套接字,然后关闭该进程
2. UDPServer.py
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind('', serverPort)
#将端口号12000与服务器的套接字绑定,也即代码显示的为该套接字分配一个端口号
#这样任何人向此IP的12000端口发送分组,该分组都将导向该套接字
print('The server is ready to receive')
while True:#while循环允许UDPServer无限期的接受并处理来自客户的分组
	message, clientAddress = serverSocket.recvfrom(2048)
	#分组的数据被放置到变量message中,源地址被放置到变量clientAddress中
	modifiedMessage = message.decode().upper()
	#将报文从字节转换为字符串后,从小写变成大写
	serverSocket.sendto(modifiedMessage.encode(),clientAddress)
	#将转换后的字符串返回给客户

2.7.2 TCP套接字编程

  • TCP是一个面向连接的协议
  • 客户和服务器能够开始互相发送数据之前,它们先要握手和创建一个TCP连接
  • TCP连接的一端与客户套接字相联系,另一端与服务器套接字相联系
  • 创建的TCP连接,将客户套接字地址与服务器套接字地址关联起来
  • 使用TCP连接,当一方向另一方发送数据时,只需要经过套接字将其丢入TCP连接,而不用为其附上目的地址

交互过程:

  1. TCP服务器在客户试图发起接触前必须作为进程运行起来
  2. 服务器程序必须具有一扇特殊的门(特殊的套接字),该门欢迎来自运行在任意主机上的客户进程的某种初始接触(欢迎之门,下文中TCP套接字对象serverSocket)
  3. 随着服务器进程的运行,客户进程能够向服务器发起一个TCP连接
  4. 客户生成其TCP套接字时,指定了服务器中的欢迎套接字的地址
  5. 生成其套接字后,该客户发起了一个三次握手并创建与服务器的一个TCP连接(发生在运输层,对于客户和服务器程序是完全透明的)
  6. 在三次握手期间,客户进程敲服务器进程的欢迎之门。当该服务器“听”到敲门声时,它将生成一扇新门(更精确地讲是一个新套接字),它专门用于特定的客户,称为连接套接字(connectionSocket),用于随后为每个客户通信而生成的套接字
    在这里插入图片描述
    如图2-27所示,客户套接字和服务器连接套接字直接通过一根管道连接,客户进程不仅能向它的套接字发送字节,也能从中接收字节
  • 在这里插入图片描述
1.TCPClient.py
from socket import *
serverName = 'servername'
serverPort = 12000
clientSocket = socket(AF_INET,SOCK_STREAM)
#第二个参数说明是TCP连接,创建客户端套接字未指定端口号,让操作系统执行
clientSocket.connect((serverName,serverPort))
#建立TCP连接,执行三次握手,然后客户端和服务器端建立起一个TCP连接
sentence = raw_input('Input lowercase sentence:')
clientSocket.send(sentence.encode())
#发送时直接通过TCP连接发送,因而不需要再提供地址
modifiedSentence = clientSocket.recv(1024)
print('From Server: ', modifiedSentence.decode())
clientSocket.close()
2.TCPServer.py
from socket import *
serverPort = 12000
serverSocket = socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
#将服务器端口号与该套接字绑定(欢迎之门)
serverSocket.listen(1)
#让服务器聆听来自客户的TCP请求,参数定义了请求连接的最大数
print('The server is ready to receive')
while True:
	connectionSocket, addr = serverSocket.accept()
	#客户敲该门时,serverSocket调用accept()方法,在服务器中创建了一个称为connectionSocket的新套接字,由这个特定的客户专用
	sentence = connectionSocket.recv(1024).decode()
	capitalizedSentence = sentence.upper()
	connectionSocket.send(capitalizedSentence.encode())
	connectionSocket.close()

参考文献

  • 计算机网络自顶向下方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值