计算机通信与网络
前言
参考资料:花猪のBlog
《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》
第一章:计算机网络概述
为了更好的理解Internet(互联网)这个概念,先从简单的网络概念说起:通俗的理解网络,就是由许多节点和边组成的系统。当我们把这些节点和边具象化之后,计算机网络以及Internet的概念就更容易理解了。
计算机网络
通俗的解释计算机网络的概念:联网的计算机所构成的系统。
其“节点”分为两类:分别为主机节点以及数据交换节点。
主机节点: 主机及其上运行的应用程序(是数据的源或目标)。
举例:ipad、手机、智能冰箱…
数据交换节点: 路由器、交换机等网络交换设备(既不是数据的源也不是目标,而是数据的中转节点)。
其“边”(通信链路)同样分为两类:分别为接入网链路以及主干链路。其作用是将各个节点连接在一起。
- 接入网链路:主机连接到互联网的链路。
- 主干链路:路由器之间的链路。
仅仅依靠所谓的“节点”和“边”是无法进行互联网间的通信的,还有一个要素就是协议。
- 协议(protocol):定义了在两个或多个通信实体之间交换的报文的格式和顺序,以及报文发送和/或接收一条报文或其他事件所采取的动作。
Internet 中所有的通信行为都受协议制约。
至此我们可以大致理解计算机网络的概念。
Internet(互联网)
以TCP/IP协议为主的一簇协议,由该协议支撑起的计算机网络。
我们可以从两方面理解到底何为Internet:一个方面是从Internet的具体构成角度(即上文所提),另一方面是从服务的角度来理解。
从具体构成的角度
数以亿计的、互联的计算设备,具体包括:
主机(host)= 端系统(end system)
在操作系统中驻留的网络应用程序
通信链路
举例:光纤、同轴电缆、无线电、卫星
传输速率 = 带宽(bps)
注意区分: 存储常用字节Byte:K/M/G层级为2^10进制 传输常用比特Bit:K/M/G层级为10^3进制
分组交换设备:转发分组(packets)。
举例:路由器、交换机…
协议:控制发送、接收消息。
举例:TCP、IP、HTTP、FTP、PPP…
Internet标准:
RFC(Request for comments):请求评述
IETF(Internet Engineering Task Force):互联网工程任务组
Internet即“网络的网络”
理解: 很多网络通过网络互联设备连接在一起 网络之下还包括很多小网络 小网络之间也可以任意互联
从服务的角度
分布式的应用进程以及为分布式应用进程提供通讯服务的基础设施。
基础设施:包括主机以及应用层以下的所有协议实体。
使用通信设施进行通信的分布式应用
举例:Web、VoIP、email、分布式游戏、电子商务、社交网络…
通信基础设施为apps提供编程接口(通信服务):将发送和接收数据的apps与互联网连接起来。
通信服务分为两种: 面向连接的服务:以TCP/IP协议向应用进程提供服务的形式。 无连接的服务:以UDP协议向应用进程提供服务的形式。
网络结构
网络结构主要由三个部分组成:网络边缘(Edge)、网络核心(Core)、接入网(Acess)\物理媒体
- 网络边缘:包括应用进程(程序)以及为其提供硬件基础服务的主机。边缘上运行的网络应用是网络存在理由。
- 网络核心:包括网络交换节点(路由)以及节点间的通信链路。边缘主机只有通过接入网连接到网络核心才可以实现相互间的信息传递。
- 接入网:有线或无线的通信链路。其作用是将边缘的主机系统接入到网络核心中去。
网络边缘
网络边缘就是端系统(主机),包括网络应用(如:Web、Email)和支持网络应用的硬件设备。应用进程可以说是整个网络系统存在的理由,其中不同边缘的应用进程通过网络进行数据交换。
应用进程间的通讯模式有两种:
- C/S模式(客户端/服务器):有着明确的客户端以及服务器。其特点也是该模式比较致命的问题:扩展性差。一个服务器的请求载荷是有限的,随着客户端的请求载荷增加,服务器的压力会越来越大,处理能力就会逐渐下降。一旦请求载荷超过某一个阈值时,服务器的处理能力就会出现断崖式下跌。目前的解决方式就是增加服务器的部署。
- P2P模式(peer-peer):没有明确的客户端或者服务器的界限。每一个分布式的应用进程既可以是客户端,又可以是服务器。这样的模式可以很好地解决C/S模式中扩展性差的问题,因为随着请求服务的节点增加,从某种意义上来说提供服务的节点也在相应地增加。(实例:迅雷、BitTorrenth)
基础设施为网络应用提供的服务有两种方式:
理解基础设施的概念:在网络应用(应用进程)下层的所有内容,包括主机、接入网、网络核心等,都统一理解为基础设施。 两种服务方式的目的都是在端系统之间传输数据。
面向连接的通信方式:
代表:TCP服务(Transmission Control Protocol,传输控制协议)
有握手:目的是两个通信主机间为连接建立状态,有一个数据传输前的准备的过程。
特性:
- 可靠地、按顺序地传送数据:不同端系统间的通信归根到底都是数据通过底层的物理信道进行传输,如何保证物理信息在传输时准确,TCP服务给予保证。
- 流量控制:在信息传输时存在这样一种情况,即服务器的能力很强,可以高速地发送大量数据,但是信息接收方(客户端)接收、处理信息的能力很弱,二者的速度不匹配,信息传输就容易造成错误。TCP协议实体可以发送反馈,从而协调好发送方和接收方的速度,致使发送方不会淹没接收方。
- 拥塞控制:信息传输时还有一种情况:信息发送和接收双方的能力都很强,但是网络核心中的传输信道发生拥塞,如果此时发送方仍然不断地向外大量发送数据,很可能造成数据的丢失。TCP协议就可以根据情况判断,当网络拥塞时,控制发送方降低信息发送速率。
使用TCP的应用: HTTP (Web)、FTP (文件传送)、Telnet (远程登录)、SMTP(email)
无连接服务:
代表:UDP服务(User Datagram Protocol,用户数据报协议)
无握手:直接传输数据,没有传输前的准备过程。
特性:
数据传输不可靠
无流量控制
无拥塞控制
UDP服务不能保证信息传输的准确性,但是它的存在也具有价值。一些实时流媒体应用对于数据传输的延迟是无法接受的,UDP服务正是省去了信息传输的很多步骤从而保证了信息传输的速度。
使用UDP的应用:流媒体、远程会议、DNS、Internet电话
网络核心
网络核心由数据交换节点和其间的通信链路组成。
网络核心的主要功能是:
- 路由:决定分组采用的源主机到目标主机的路径(全局)
- 转发:将分组从路由器的输入链路转移到输出链路(局部)
通信网络大致可以按照如下方式分类:
- 电路交换网络
端到端的资源被分配给从源端到目标端的呼叫(建立起一条专有链路)。
电路交换网络的特点是资源独享,即便主机间建立连接后无数据传输,也会占用线路资源,从而使其他用户无法使用,导致资源浪费。但是这种连接方式保证了性能,多用于传统电话网络,而不适用计算机间的连接。
计算机之间的通信不像电话,它具有很强的突发性,两台主机建立连接后并不是时时刻刻都在进行数据传输。(如浏览网页,用户发起请求之后的很长一部分时间都在进行页面浏览,此时并没有数据传输)
为了提高电路交换网络的使用效率,网络资源(如带宽)被分成“片段”,同时被多位用户使用。像这样分成片段的方式主要有:
- 频分(Frequency-division multiplexing)
- 时分(Time-division multiplexing)
- 波分(Wave-division multiplexing)
频分(FDM):将带宽分成几个片段,不同的用户使用不同的片段。
时分(TDM):将带宽按周期分为成许多片段,每一个周期再分为几个不同的时隙(slot),每位用户固定使用其中的一个时隙。
波分(WDM):多用于光电路传输,把光信号分成不同波段,分给不同用户使用。
- 分组交换网络
将要传输的数据分成一个个的单位:分组/包(packet)
与电路交换网络不同,采用分组交换网路通信时,数据传输会占用通信链路的全部带宽。
主机间的数据传输过程如图:转发节点接收前一个节点传来的分组,并存储起来,等分组的全部传输完成之后,再将数据传输给下一个节点。(存储-转发)
需要注意的是:每一个节点都必须接收分组的全部之后才能向后传递。如果边接收分组,边向后传输,就会造成多段通信链路全部处于占用状态,致使其他用户无法使用。分组也就失去了意义。
例子:如图,长度为L = 7.5Mbits的分组,在一个速率为R = 1.5Mbps的链路中传输,三次存储-转发的延时为3 × (7.5 / 1.5)s = 15s.
分组交换网络的优势就是:按需使用。即有需要时才占用网络资源。
但是这较于电路交换网络的延迟会高很多,延迟的具体组成分为两部分:
- 节点对分组进行存储
- 排队时间
分组交换的排队延迟和丢失:
当转发节点的数据到达速率>链路的输出速率时,分组将会进行排队,如果路由器的缓存用尽,分组将会丢失。
为了保证数据可靠地传输,就需要协议来约束:拥塞控制
了解了分组交换网络的数据传输原理,就可以引出统计时分多路复用(statistical time division multiplexing,STDM):
这个概念很像时分多路复用(TDM),区别在于:由于每个分组的传输时间不同,因此对于带宽无绝对的时间划分方式(每个时隙是不同的)。
同样的网络资源,分组交换网络较电路交换网络允许更多的用户使用。
存储-转发
分组的存储转发一段一段从源端到目标端,按照有无网络层的连接可分为两种:
- 数据报(datagram)网络
- 虚电路(virtual circuit)网络
数据报网络:
- 在通信之前无需建立连接,一有数据就传输。
- 每一个分组都独立路由(路径不一样,可能会失序)。
- 源主机发送给目标主机的分组,携带了目标主机的完整地址,路由器根据分组的目标地址进行路由。
- 路由器不会维护主机间的通讯状态。
虚电路网络:
- 在通信之前,主机间需要先通过信令建立连接,分组传输路径保持不变。
- 每个分组都带标签(虚电路标识VCID),标签决定了下一个跳转。
- 路由器会维持每个呼叫的状态信息。
接入网和物理媒体
将端系统和边缘路由器连接的方式可以分为三类:住宅接入网络;单位接入网络(学校、公司);无线接入网络。
注意接入网络的带宽分为:共享;专用。(比如:有一个接入住宅大楼的网络是专用的,分发到每个住户的网络是共享这一接入网的。)
接入网
- 住宅接入:
调制解调器(moden):将上网数据调制加载音频信号上,在电话线上传输,在局端将其中的数据解调出来,接入网络核心;反之亦然。
拨号调制解调器:56kbps的速率直接接入路由器(通常更低)。不能同时上网和打电话。
DSL(digital subscriber line):采用现存的到交换局DSLAM的电话线。
依然采用调制解调的方式 带宽其中0k~4k的部分用于传播语音,其他的部分分为上行和下行数据传输(通常下行速度更大,称为ADSL(非对称)) DSL线路上的数据被传到互联网 DSL线路上的语音被传到电话网 小于2.5Mbps上行传输速率(typically < 1 Mbps) 小于24Mbps下行传输速率(typically < 10 Mbps)
线缆网络:有线电视信号线缆双向改造。(利用电视线传输)
带宽其中一部分用于传播电视信号,其他的部分分为上行和下行数据传输。 FDM:在不同频段传输不同信道的数据,数字电视和上网数据(上、下行)。 HFC(hybrid fiber coax,混合光纤同轴网):光纤传输系统与同轴电缆分配网相结合。(非对称:最高30Mbps下行传输速率,2Mbps上行传输速率) 线缆和光纤网络:将各个家庭用户接入到ISP路由器。 各用户共享到线缆头端的接入网络。(注意与DSL不同,DSL中每个用户都有一个专用的线路到CO(central office))
电缆模式
家庭网络
企业接入网络:
经常被企业或者大学等机构采用(10Mbps、100Mbps、1Gbps、10Gbps传输率。现在,端系统经常直接接到以太网络交换机上)
无线接入网络:
各无线端系统共享无线接入网络(端系统到无线路由器)
无线LANs(建筑物内部) 广域无线接入
物理媒体
几个概念:
bit:在发送-接受对间传播 物理链路:连接每个发送-接受对之间的物理媒体 导引型媒体(看得见、摸得着):信号沿着固体媒介被引导。(eg:同轴电缆、光纤、双绞线) 非导引型媒体(看不见):开放的空间传输电磁波或者光 信号,在电磁或者光信号中承 载数字数据。
双绞线、同轴电缆、光纤(导引型媒体)
无线链路(非导引型媒体)
Internet结构和ISP
ISP:Internet Service Provider
任何一个端系统都是通过接入ISP接入网络,因此就会有很多ISP。由于网络用户数量非常之多,因此也会有许多ISP,ISP必须是互联的,只有这样端系统之间才可以通信。那么ISP之间是如何互联的?
有一种办法是将他们两两互联,但是这会存在一个问题:ISP数量非常之多,在数量达到一定的情况下,再增添一个ISP所耗费的成本会非常巨大,整个体系的性能也会下降。因此这个方法并不可行,我们称其为:不可扩展。
当意识到这点之后,人们就会想到利用一个global ISP作为“桥梁”,来将各个接入ISP连接起来。
一个global ISP可以完成“桥梁”的工作,很明显这种做法一定是有利可图的,所以为了不让其出现垄断的局面(垄断总是不好的),所以这时一定会有其他的ISP来参与竞争(如图:部分接入网连接ISP A,部分连入ISP B…)。
有竞争必然也有合作,运营商们可以互相商量,给彼此提供一个接口,这样所有的客户端就都可以相互通信。
ISP之间连接方式有两种:
直接连接(peering link) 通过IXP(Internet exchange point,网络交换点)来连接
接下来该种通信业务就会细分,出现所谓的区域性网络,他们可以更加方便地为某一地区提供通信服务,同时将与之接入的边缘ISP接入到全局的ISP。
然后内容提供商网络(Internet Content Providers,ICP,例:Google,Microsoft),可能会构建他们自己的网络,将它们的服务、内容更 加靠近端用户,向用户提供更好的服务,减少自己的运营支出。
至此,整个网络体系就构成了当今的局面,即网络的网络。
Internet结构
是一个具有层次的结构:
- 第一层ISP(中心):国家/国际覆盖,速率极高。(如UUNet, BBN/Genuity, Sprint, AT&T)
- 直接与其他第一层ISP相连
- 与大量的第二层ISP和其他客户网络相连
- 通过Peer或IXP连接
- 第二层ISP:更小些的 (通常是区域性的) ISP。
与一个或多个第一层ISPs连接,也可能与其他第二层ISP相连。
通过Peer或IXP连接
- 第三层ISP与其他本地ISP: 接入网 (与端系统最近)
分组延时、丢失和吞吐量
分组丢失和延时发生的原因:分组在传输过程中,会在路由器的缓冲区形成分组队列,分组等待排到队头,就会被传输至下一节点。这一排队过程就会产生排队延时(还有其他的延时,后面会详细提到)。如果缓冲区容纳不下被传输来的分组(队列容量不够),就会发生分组丢失的现象。
分组延时
- 节点处理延时(nodal processing delay):节点在收到分组时,为处理分组所花费的时间。
检查bit级差错
检查分组首部和决定将分组导向何处
微秒级
- 排队延时(queuing delay):分组在节点中排队等待被发送所花费的时间。
时间长短依赖于路由的拥塞程度(是不确定的)
毫秒-微秒级
- 传输延时(transmission delay):数据从节点进入到传输媒体所耗费的时间。
R = 链路带宽(bps)
L = 分组长度(bits)
将分组发送到链路上的时间:T = L/R
- 传播延时(propagation delay):数据(电磁波)在物理信道上传输一定距离所耗费的时间。
d = 物理链路的长度
s = 数据信号在介质上传播的速度(约为2×108 m/sec)
传播延时:T = d/s
下面以车队的例子来类比:
延时小结:
排队延时取决于流量强度:
R = 链路带宽 (bps) L = 分组长度 (bits) a = 分组到达队列的平均速率
流量强度 = La/R
La/R ~ 0: 平均排队延时很小 La/R -> 1: 延时变得很大 La/R > 1: 比特到达队列的速率超过了从该队列输出的速率,平均排队延时将趋向无穷大! 注意:设计系统时流量强度不能大于1,会导致分组丢失!
Traceroute 诊断程序: 提供从源端,经过路 由器,到目的的延时测量。
沿着目的的路径,向每个路由器发送3个探测分组
路由器 i 将向发送方返回一个分组
发送方对发送和回复之间间隔计时
Traceroute具体实现原理: 利用了ICMP(Internet Control Message Protocol,互联网控制报文协议)。这种协议下的报文数据IP头部有一个字段:TTL(Time to Live,生存时间)字段。这个字段在最初传输时会被赋值,每经过一个路由器时,TTL减1。当TTL在某一个路由器降为零时,该分组会被抛掉,并会向源主机发送一个ICMP报文——通知源主机:分组发送到该路由时被“干掉”了(并附带IP地址),所以实现每一跳的查询方式就是设置不同的TTL。当分组到达目标主机时,肯定会占用一个端口,但是在目标主机中该端口并没有进程在跑,于是目标主机就会向源主机发送另一种ICMP报文——通知源主机:分组在我这边由于目标端口不可达,“挂掉了”(并附带IP地址)。这就是具体的工作原理。
例子:
上图在第7步和第8步延时出现了陡增的情况,很有可能是跨洋链路(该段链路特别长)
吞吐量(Throughput)
在源端和目标端之间传输的速率(数 据量/单位时间)
瞬间吞吐量: 在一个时间点的速率
平均吞吐量: 在一个长时间内平均值
瓶颈链路:端到端路径上,限制端到端吞吐的链路。(短板效应) 主机A到主机B之间的通信链路一定是公用的,我们假设有10个用户在用同一段链路(该链路带宽最小),那么A到B的连接就会占用这最小链路带宽的十分之一。这十分之一带宽就是A到B的瓶颈带宽,是它限制了A到B的吞吐量。
协议层次及服务模型
网络是一个复杂的系统。一般对于实现复杂的组织与功能的思路就是分模块,把不同的小功能分模块实现,然后总体实现一个复杂庞大的功能。计算机网络功能的实现同样利用这个思路,利用层次化方式实现复杂的网络功能。
层次化的具体思路:
- 将网络复杂的功能分层功能明确的层次,每一层实现了其中一个或一组功能,功能中有其上层可以使用的功能:服务
- 本层协议实体相互交互执行本层的协议动作,目的是实现本层功能, 通过接口为上层提供更好的服务
- 在实现本层协议的时候,直接利用了下层所提供的服务
- 本层的服务:借助下层服务实现的本层协议实体之间交互带来的新功能(上层可以利用的)+ 更下层所提供的服务
服务(Service):低层实体向上层实体提供它们之间的 通信的能力,是通过原语(primitive)来操作的,是垂直关系。
协议(protocol):对等层实体(peer entity)之间在相互通信的过程中,需要遵循的规则的集合,是水平关系。
协议和服务的关系:协议需要下层提供的服务才能实现,协议实现的目的是为了向上层提供更好的服务。本层的服务用户只能看见服务而无法看见下面的协议,下面的协议对上面的服务用户是透明的(看不见的)。
一些术语介绍:
实体(entity):表示任何可发送或接收信息的硬件或软件进程。
服务(Service):低层实体向上层实体提供它们之间的通信的能力。
服务访问点 SAP (Services Access Point) :上层使用下层提供的服务通过层间的接口。
原语(primitive):上层使用下层服务的形式,高层使用低层提供的服务,以及低层向高层提供服务都是通过服务访问原语来进行交互的。
一个服务提供者(service provider)可能会向上层用户(service user )提供不同的服务,提供服务的具体接口就是层间的服务访问点(SAP),服务的具体形式就是原语。
服务的类型:
- 面向连接的服务(Connection-oriented Service):
- 连接(Connection):两个通信实体为进行通信而建立的一 种结合。
- 面向连接的服务通信的过程:建立连接,通信,拆除连接。
- 适用范围:对于大的数据块要传输; 不适合小的零星报文。
- 特点:保序(也不尽然)。
- 无连接的服务(Connectionless Service):两个对等层实体在通信前不需要建 立一个连接,不预留资源;不需要通信双方都是 活跃。
- 特点:不可靠、可能重复、可能失序。
- 适用范围:适合传送零星数据。
分层处理和实现复杂系统的好处:
概念化:结构清晰,便于标示网络组件,以及描述其相互关系。(分层参考模型)
结构化:模块化更易于维护和系统升级。(改变某一层服务的实现不影响系统中的其他层次)
分层也具有有害的地方:分层实现一个功能时,需要不同层次时时交换信息数据,那么整体的效率就会降低。(每一层都要做差错检测)
层具有的功能:
- 差错控制(error control):使得两个对等体(不同端系统中相同的层次)之间的逻辑通信更加可靠。
- 流量控制(flow control):防止发送方淹没接收方。
- 分段与重组(segmentation and reassembly):在发送端将大数据块分割成小数据块,在接收端将小数据块重新组合成原来的大数据块。
- 多路复用(multiplexing):允许多个上层会话共享一个下层连接。
- 连接建立(connection setup):握手。
Internet协议栈
从上至下层次划分为:
- 应用层(application):完成应用报文之间的交互。(实现各种网络应用)
数据单元:**报文(message)**
eg:FTP、SMTP、HTTP
- 传输层(transport):实现进程到进程之间的数据传输。
数据单元:**报文段(segment)**
eg:TCP、UDP
- 网络层(network):实现端到端(源主机-目标主机)的以分组为单位的数据传输。
数据单元:**分组(packet)**;如果是无连接的方式:**数据报(datagram)**
eg:IP、routing protocols(路由协议)
- 链路层(link):在相邻网络节点间以帧为单位传输数据。
数据单元:**帧(frame)**
eg:PPP(点对对协议)、802.11(wifi)、Ethernet
- 物理层(physical):在线路上传送bit。(把数字数据转换成物理信号,使其承载于媒体之上)
数据单元:**位(bit)**
Internet实际上只定义了上三层协议(应用层、传输层、网络层),下面的链路层和物理层被统一为网络接口层。
协议栈不同层中的协议并未实现全覆盖,有些应用可以直接跨层,由更低层的协议实现。
OSI参考模型
从上至下层次划分为:
应用层(application)
表示层(presentation):允许应用解释传输的数据。(关心交换数据的格式)
表示层的目的是表示出用户看得懂的数据格式,实现与数据表示有关的功能。主要完成数据字符集的转换、数据格式化和文本压缩、数据加密、解密等工作。
会话层(session):数据交换的同步,检查点,恢复。
传输层(transport)
网络层(network)
链路层(data link)
物理层(physical)
表示层与会话层的功能在TCP/IP协议栈中由应用层完成。
OSI参考模型包括了体系结构、服务定义和协议规范三级抽象。
封装与解封装
源主机向目标主机传送报文的真正流程——不断地封装与解封:
上层报文的传输需要借助层间接口,依托于下层的服务,在不同层加入相应的控制信息,形成本层的数据单元,继续向下传递,直到物理层将每一个bit传送给通信链路(这是封装的过程)。通过链路交换机,底部物理层会还原数据形成链路层的数据单元(帧),链路层查询帧头部的目标MAC地址,并查询该交换机的栈表(或交换表),并决定将帧从哪一个端口放出,接着就交给该端口的网卡,转换成对应物理层的bit,将其释放到通信链路中。通过路由器,先向上传递形成帧,再将帧转换为网络层的数据单元(分组),网络层从分组获取目标的IP信息,并查询网络层的转发表,决定将数据从哪一个网口释放出去,再形成对应的帧向下传递,进而转为bit由物理层将其传输到通信链路。就这样数据不断传输,最后到达目标主机,并不断解封装形成应用层的报文。
第二章:计算机网络|应用层
互联网层次中,应用层的协议是最多的。
网络应用的原理:网络应用协议的概念和实现方面
- 运输层的服务模型(transport-layer service models)
- 客户/服务器模式(client-server paradigm)
- P2P模式(peer-to-peer paradigm)
网络应用的实例:互联网流行的应用层协议
- HTTP
- FTP
- SMTP / POP3 / IMAP
- DNS
编程:网络应用程序创建:
- socket API / E-mail / web / instant messaging: (QQ), Wechat (即时消息) / remote login (远程登录) / P2P file sharing (文件共享) / multi-user network games (多用户网络游戏) / streaming stored video clips (流式存储视频) / Social networks (社交网络) / voice over IP (IP电话) / real-time video conferencing (实时视频会议) / grid computing/Cloud computing (网格计算/云计算)
创建一个新的网络应用:
编程:
- 在不同的端系统上运行(run on different end systems)
- 通过网络基础设施提供的服务,应用进程彼此通信(communicate over network)
- 例如:Web服务器软件与浏览器软件通信(web server software communicates with browser software)
无需为网络核心设备编写程序(no need to write software for networkcore devices):
- 网络核心不会运行用户应用(network core devices do not run user applications)
- 网络应用只在端系统上存在 ,快速网络应用开发和部署(applications on end systems allows for rapid app development, propagation)
应用层协议原理(Principles of network applications)
可能的应用架构:
客户-服务器模式(C/S:client/server)
对等模式(P2P:Peer To Peer)
混合体:客户-服务器和对等体系结构
浏览器/服务器模式(B/S:Brower/Server)是C/S架构的一种特例
客户-服务器(C/S)体系结构
服务器:
- 一直在运行
- 固定的IP地址和周知的端口号(约定)
- 服务器是数据中心(包括软件资源,硬件资源,数据资源)
- 扩展性差(性能在访问数量达到一定程度时会出现断崖式下跌)
客户端:
- 主动与服务器连接(服务器先运行,客户端后访问)
- 与互联网有间歇性的连接
- 可能是动态IP地址
- 不直接与其他客户端通信
对等体(P2P)体系结构
(几乎)没有一直运行的服务器
任意端系统之间可以进行通信
每一个节点既是客户端又是服务器
自扩展性:新peer节点带来新的服务能力,当然也带来新的服务请求
参与的主机间歇性连接且可以改变IP地址
带来的问题就是:难以管理
实例:迅雷
C/S和P2P体系结构的混合体
Skype:
文件(目录)查询:集中式
存在一个中心服务器
文件分发(传输):P2P
客户端连接可以不通过服务器直接连接
即时通讯(以QQ为例):
- 两个用户之间的聊天是P2P方式
- 当用户上线时,向中心服务器注册其IP地址
- 用户通过中心服务器找到好友IP地址
进程通信(Processes communicating)
进程:在主机上运行的应用程序
进程间的通信:
在同一个主机内:使用进程间通信机制通信( 操作系统定义),无需协议。
在不同主机内:通过交换报文(Message)来通信。
- 使用OS提供的通信服务
- 借助传输层提供的服务,按照应用协议交换报文
客户端进程:发起通信的进程 服务器进程:等待连接的进程 注意:P2P架构的应用也有客户端进程和服务器进程之分
分布式进程通信需要解决的问题:
- 问题1:进程标识(自身)和寻址(让对方找得到自己)问题。
- 问题2:传输层-应用层是如何提供通信服务。
- 位置:层间界面的SAP(TCP/IP :socket)
- 形式:应用程序接口API(TCP/IP :socket API)
- 问题3::如何使用传输层提供的服务,实现应用进程间的报文交换,实现应用。
- 定义应用层协议:报文格式,解释,时序等
- 编制程序,使用OS提供的API ,调用网络基础设施提供通信服务传报文,实现应用时序等;
- 问题1:对进程进行编址:
进程为了接收报文,必须有一个标识,即:SAP(当然发送也需要标识)
主机IP:唯一的32位IP地址(仅仅有IP地址不能够唯一标示一个进程;在一台端系统上有很 多应用进程在运行) 所采用的传输层协议:TCP or UDP 端口号(Port Numbers) 一些知名端口号的例子:HTTP: TCP 80 Mail: TCP 25 TCP和UDP的端口号是不同的
一个进程用IP地址和端口号(port)标识。
本质上,两个主机进程之间的通信是由2个端节点(end point)构成
- 问题2:传输层-应用层提供的服务:
层间接口必须要携带的信息(3类)
- 要传输的报文(对于本层来说就是SDU)
- 谁传递的信息:本方应用进程的标识,即本方IP+TCP(UDP) 端口
- 信息要传递给谁:对方应用进程的标识,即对方IP+TCP(UDP) 端口
传输层实体(tcp或者udp实体)根据这些信息进行TCP报文段(UDP报文段)的封装
- 源端口号,目标端口号,数据等
- 将IP地址往下交IP实体,用于封装IP数据报:源IP,目标IP
Socket(套接字)
进程通过套接字发送或接受报文。
可以把套接字比作一道门。发送进程将报文推出门户,发送进程依赖于传输层设施在另外一侧的门将报文交付给接收进程,同样的,接收进程从另外一端的门户收到报文(依赖于传输层设施)
传输层提供的服务-层间信息的代表:
层间建立连接后需要传输大量的信息,如果Socket API 每次传输报文,都携带如此多的信息,太繁琐易错,不便于管理。为了解决这个问题,出现了Socket(套接字,实际上就是用一个整数表示两个应用实体之间的通信关系 ,是一个本地标识)。
- TCP之上的套接字:
对于使用面向连接服务(TCP)的应用而言,套接字是4元组的一个具有本地意义的标识。
4元组:源IP,源port,目标IP,目标port
唯一的指定了一个会话(2个进程之间的会话关系)
应用使用这个标示,与远程的应用进程通信
不必在每一个报文的发送都要指定这4元组
简单,便于管理
- UDP之上的套接字:
(由于UDP服务下的进程通信前不需要连接,前后报文都是独立传输的,且可能传输给不同的分布式进程。所以只能用一个整数表示本应用实体的标识。)
对于使用无连接服务(UDP)的应用而言,套 接字是2元组的一个具有本地意义的标识。
2元组:源IP,源port
UDP套接字指定了应用所在的一个端节点(end point)
在发送数据报时,采用创建好的本地套接字(标识 ID),就不必在发送每个报文中指明自己所采用的 ip和port
但是在发送报文时,必须要指定对方的ip和udp port(另外一个端节点)
问题3:如何使用传输层提供的服务实现应用
定义应用层协议:报文格式,解释,时序等
编制程序,通过API调用网络基础设施提供通信 服务传报文,解析报文,实现应用时序等
应用层协议:
该协议定义了:运行在不同端系统上的应用进程如何相互交换报文。(仅仅规范了两个进程在通信中需要遵守的规则)
交换的报文类型:请求和应答报文
各种报文类型的语法:报文中的各个字段及其描述
字段的语义:即字段取值的含义
进程何时、如何发送报文及对报文进行响应的规则
应用协议仅仅是应用的一个组成部分。一个应用还包括用户界面,本地I/O操作,业务逻辑等
公开协议:
由RFC文档定义
允许互操作
举例:HTTP、SMTP
私有协议(不公开):例如:SKype、QQ、wechat
应用需要传输层提供的服务:
- 数据丢失率(Data loss):
有些应用则要求100%的可靠数据传输(如文件),有些应用(如音频)能容忍 一定比例以下的数据丢失
实际上在看视频时是会有丢帧的情况,我们无法察觉的原因是因为采用了一些掩盖技术: 比如第二帧的画面丢失,可以选择重放第一帧或第三帧,也可以计算并播放第一、三帧求和后取均值。
延迟(Timing):
一些应用出于有效性考虑,对数据传输有严格的时间限制(如:Internet 电话、交互式游戏)
吞吐(Throughput)
一些应用(如多媒体应用)必须需要最小限度的吞吐,从而使得应用能够有效运转。一些应用能充分利用可供使用的吞吐(“弹性应用”)
安全性(Security)
机密性、数据完整性、可认证性(鉴别)…
下表是一些常见应用对传输服务的要求:
应用 | 数据丢失率 | 吞吐 | 时间敏感性 |
---|---|---|---|
文件传输 | 不能丢失 | 弹性 | 不 |
不能丢失 | 弹性 | 不 | |
Web 文档 | 不能丢失 | 弹性 | 不 |
实时音视频 | 容忍丢失 | 音频: 5kbps-1Mbps 视频:10kbps-5Mbps | 是,100ms |
存储音视频 | 容忍丢失 | 音频: 5kbps-1Mbps 视频:10kbps-5Mbps | 是,几秒 |
交互式游戏 | 容忍丢失 | 几kbps ~10kbps | 是,100ms |
即时讯息 | 不能丢失 | 弹性 | 是和不是 |
Internet传输层提供的服务:
TCP服务:
- 可靠的传输服务(不出错、不丢失、不乱序)
- 流量控制:发送方不会淹没接受方
- 拥塞控制:当网络出现拥塞时,能抑制发送方
- 不能提供的服务:延时保证、最小吞吐(带宽)保证和安全性
- 面向连接:要求在客户端进程和服务器进程之间建立连接
UDP服务:
不可靠数据传输
不提供的服务:可靠, 流量控制、拥塞控制、 延时、带宽保证、不建立连接
UDP存在的必要性:
能够区分不同的进程,而IP服务不能。(在IP提供的主机到主机/端到端功能的基础上,区分了主机的 应用进程)
无需建立连接:省去了建立连接时间,适合事务性的应用
不做可靠性的工作:例如检错重发,适合那些对实时性要求比较高而对正确性要求不高的应用。(实现可靠性是必须要付出时间代价的)
没有拥塞控制和流量控制:应用能够按照设定的速度发送数据。(在TCP上面的应用,应用发送数据的速度和主机向网络发送的实际速度是不一致的,因为有流量控制和拥塞控制)
下表展示了Internet应用及其应用层协议和传输协议
应用 | 应用层协议 | 下层的传输协议 |
---|---|---|
SMTP [RFC 2821] | TCP | |
远程终端访问 | Telnet [RFC 854] | TCP |
Web | HTTP [RFC 2616] | TCP |
文件传输 | FTP [RFC 959] | TCP |
流媒体 | 专用协议 (如RealNetworks) | TCP 或 UDP |
Internet电话 | 专用协议 (如Net2Phone) | TCP 或 UDP |
安全TCP
TCP&UDP
- 都没有加密
- 明文通过互联网传输 ,甚至密码
SSL
- 在TCP上面实现,提供加密的TCP连接(https://)
- 私密性
- 数据完整性
- 端到端的鉴别/认证
SSL在应用层
- 应用采用SSL库,SSL库使用TCP通信
SSL socket API
- 应用通过API将明文交给socket,SSL将其加密在互联网上传输
Web and HTTP
一些术语:
Web页:由一些对象组成。(对象可以是HTML文件、JPEG图像、Java小程序、声 音剪辑文件等)
Web页含有一个基本的HTML文件,该基本HTML文件又包含若干对象的引用(链接)
通过URL对每个对象进行引用
包含访问协议,用户名,口令字,端口等;(如下图)
一个网页通常是一个baseHTML文件,这个文件是HTML的形式,浏览器可以解析。其中包含各种对象,但是并不包括对象本身,而是这个对象的引用链接。(浏览器需要判断这个链接,并且去再次访问这个对象链接,从而将对象本身访问到并展示在baseHTML页面上)
HTTP(hypertext transfer protocol):超文本传输协议
Web的应用层协议
客户/服务器模式(C/S)
客户: 请求、接收和显示 Web对象的浏览器。
服务器: 对请求进行响应, 发送对象的Web服务器。
使用TCP:
- 客户发起一个与服务器的TCP连接 (建立套接字) ,端口号为80。
服务器在最初建立之时会有一个socket(waiting socket)守候在80端口。如果一个浏览器(客户端)向服务器建立连接,此时又会有一个socket(connection socket)产生(代表该服务器与客户端的会话关系)。
waiting socket比较特殊,作用就是等待其他浏览器(客户端)并发访问该服务器,而connection socket则表示会话关系,可以有多个。
服务器接受客户的TCP连接
在浏览器(HTTP客户端)与 Web服务器(HTTP服务器server)交换HTTP报文(应用层协议报文)
TCP连接关闭
HTTP是无状态的:服务器并不维护关于客户的任何信息(无状态的好处就是简单,不需要维护一些内容)
无状态:客户端向服务器发送请求,服务器接收请求,并返回响应报文,断开连接,结束。(不知道该客户端之前有没有访问过,未来还会不会接着访问)
非持久HTTP(Nonpersistent HTTP)连接
最多只有一个对象在TCP连接上发送
下载多个对象需要多个TCP连接
HTTP/1.0使用非持久连接
持久HTTP(Persistent HTTP)连接
多个对象可以在一个(在客户端和服务器之间的)TCP连接上传输
HTTP/1.1 默认使用持久连接
响应时间模型:
RTT(往返时间,round-trip time):一个小的分组从客户端到服务器,再回到客户端的时间(传输时间忽略)
响应时间:
- 一个RTT用来发起TCP连接
- 一个 RTT用来HTTP请求并等待HTTP响应
- 文件传输时间
在非持久HTTP连接下请求一个文件(对象)的时间 = 2RTT + 传输时间
非持久HTTP的缺点:
请求每个对象需要2个 RTT
操作系统必须为每个TCP连接分配资源
浏览器通常打开并行TCP连接 ,以获取引用对象
并行连接,即同时开启多个连接请求不同对象。
1index.html + 10jpeg = 2RTT(建立连接) + 2RTT(并行请求对象) = 4RTT
持久HTTP(Persistent HTTP)连接:
服务器在发送响应后,仍保持TCP连接
在相同客户端和服务器之间的后续请求和响应报文通过相同的连接进行传送
客户端在遇到一个引用对象的时候,就可以尽快发送该对象的请求
非流水方式的持久HTTP(Persistent without pipelining):
客户端只能在收到前一个响应后才能发出新的请求
每个引用对象需要一个RTT
1index.html + 10jpeg = 2RTT(建立连接) + 10×1RTT(10jpeg) = 12RTT
流水方式的持久HTTP(Persistent with pipelining):
HTTP/1.1的默认模式
客户端遇到一个引用对象就立即产生一个请求
所有引用(小)对象基本上只用一个RTT时间就能满足
1index.html + 10jpeg = 2RTT(建立连接) + 1RTT(10jpeg) = 3RTT
HTTP报文
有两种类型的HTTP报文:request(请求报文)、response(响应报文)。
HTTP请求报文:
请求报文的通用格式如下图:
提交表单有两种方式:
- Post方式:
- 网页通常包括表单输入
- 输入的数据放在实体(entity body )部分上传到服务器
- URL方式:
- 方法:GET方法
- 输入的数据放在URL中上传
方法类型:
HTTP/1.0
GET
POST
HEAD(要求服务器在响应报文中不包含请求对象→维护或者建立索引时引用)
HTTP/1.1
GET, POST, HEAD
PUT(将实体中的文件上载到URL字段规定的路径→通常做网页内容的维护)
DELETE(删除URL字段规定的文件)- Post方式:
HTTP响应报文:
HTTP响应状态码:
- 200 OK:请求成功,请求对象包含在响应报文的后续部分。
- 301 Moved Permanently:请求的对象已经被永久转移了;新的URL在响应报文的Location: 首部行中指定。客户端软件自动用新的URL去获取对象。
- 400 Bad Request:一个通用的差错代码,表示该请求不能被服务器解读。
- 404 Not Found:请求的文档在该服务上没有找到。
- 505 HTTP Version Not Supported
用户-服务器状态:cookies
大多数主要的门户网站使用 cookies
cookies有4个组成部分:
在HTTP响应报文中有一个cookie的首部行
在HTTP请求报文含有一个cookie的首部行
在用户端系统中保留有一个cookie文件,由用户的浏览器管理
在Web站点有一个后端数据库
客户端(浏览器)在第一次向服务器发送请求时不携带cookie,服务器也会判断,这是第一次访问,并会在响应报文中设置一个cookie,客户端收到响应报文后会将服务器发送来的cookie存到本地,下一次再访问该服务器时就会携带上该cookie值,此时服务器就可以凭借cookie值去判断、分析客户端的状态。
通过cookie,可以将HTTP从一个无状态的协议转换为一个有状态的协议。
cookies可以带来以下内容:
- authorization 授权(用户验证)
- shopping carts 购物车
- recommendations 推荐
- user session state (Web e-mail) 用户会话状态
如何维护状态:
协议端节点:在多个事务上 ,发送端和接收端维持状态(不会保留在中间节点中) http报文携带状态信息
cookies的副作用:
- Cookies允许站点知道许多关于用户的信息(隐私)
- 网站记录用户信息并分析用户行为(可能将它知道的东西卖给第三方)
- 使用重定向和cookie的搜索引擎还能知道用户更多的信息(姓名、电话、邮箱等)
Web caches(proxy server)缓存(代理服务器)
目标:不访问原始服务器,就可以满足客户的请求。
缓存既是客户端又是服务器。
通常缓存是由ISP安装 (大学、公司、居民区ISP)
浏览器将所有的HTTP请求发给缓存(代理服务器)
- 在缓存中的对象:缓存直接返回对象
- 如对象不在缓存,缓存请求原始服务器,然后再将对象返回给客户端
优势:
- 降低客户端的请求响应时间
- 可以大大减少一个机构内部网络与Internent接入链路上的流量
- 互联网大量采用了缓存: 可以使较弱的ICP也能够有效提供内容(快速分发内容)
条件GET方法
使用缓存有一个风险:客户端访问到的缓存中的数据,在原始服务器中已修改,结果就是拿到旧数据。
为此HTTP协议做了一个升级:Conditional GET(条件GET)
目标:如果缓存器中的对象拷贝是最新的,就不要发送对象
- 缓存器: 在HTTP请求中指定缓存拷贝的日期
If-modified-since:<date’>
服务器:
- 如果缓存拷贝没有改变,则响应报文不包含对象: HTTP/1.0 304 Not Modified - 如果缓存拷贝改变,则返回数据:HTTP/1.0 200 OK <data’>
Short URL
把普通网址,转换成比较短的网址。(比如:http://t.cn/RlB2PdD)
- 微博;这些限制字数的应用里都用到这种技术。
- 百度短网址:http://dwz.cn/
- google短网址: https://goo.gl/
当我们在浏览器里输入 http://t.cn/RlB2PdD 时会经历以下步骤:
浏览器解析DNS,获取域名对应的IP;
当获取到IP时,会往这个IP地址发送http的get请求以获取到RlB2PdD对应的长链接地址;
HTTP通过301转到对应的长链接URL;
注意:这里为什么使用301? 301是永久性转移(重定向)。也就是说,这个短地址一经生成就不会发生变化了。
FTP(文件传输协议)
向远程主机上传输文件或从远程主机接收文件
建立在TCP基础之上
客户/服务器模式:
客户端:发起传输的一方
服务器:远程主机ftp: RFC 959
ftp服务器:端口号为21
FTP客户端与FTP服务器通过端口21联系,并使用TCP为传输协议 客户端通过控制连接获得身份确认(通过TCP)(用户名和口令,全部都为明文) 客户端通过控制连接发送命令浏览远程目录(可以上传、下载) 收到一个文件传输命令时,服务器打开一个到客户端的TCP数据传输连接(客户端的20号端口,由服务器主动建立),控制信息/指令和数据传输的连接是不一样的。 一个文件传输完成后,服务器关闭连接 服务器打开第二个TCP数据连接用来传输另一个文件 控制连接: 带外( “out of band” )传送(只能建立一个) 数据连接:带内传送(可以建立多个) FTP服务器维护用户的状态信息: 当前路径、用户帐户与控制连接对应(FTP是一个有状态的协议)
FTP在控制连接上以ASCII文本方式传送:
命令样例:
USER username PASS password LIST:请服务器返回远程主机当前目录的文件列表 RETR filename(重复性下载文件):从远程主机的当前目录检索文件 (gets) STOR filename(上载文件):向远程主机的当前目录存放文件 (puts)
返回码样例:(状态码和状态信息 (同HTTP))
331 Username OK, password required 125 data connection already open; transfer starting 425 Can’t open data connection 452 Error writing file
Electronic mail(Email)
电子邮件(Email)的三个主要组成部分
user agents (用户代理)
又名 “邮件阅读器” 撰写、编辑和阅读邮件 如Outlook、Foxmail 输出和输入邮件保存在服务器上
mail servers(邮件服务器)
邮箱中管理和维护发送给用户的邮件 输出报文队列保持待发送邮件报文 邮件服务器之间的SMTP协议:发送email报文 客户:发送方邮件服务器 服务器:接收端邮件服务器 两个作用: 用户代理配置好邮件服务器的IP地址、端口号,然后用户代理把邮件发送给邮件服务器的队列当中。邮件服务器会把队列中的邮件依次发送到目标邮件服务器中。 (用户代理发邮件到邮件服务器用的是SMTP协议) 然后目标邮件服务器接收到邮件后会把邮件放到相应用户的目录(邮箱)当中。收件人运行客户代理,从邮件服务器中相应的自己的邮箱中把信件拉回到本地。 (邮件服务器发给目标邮件服务器使用的是SMTP协议) (“拉”邮件的协议有三种:POP3、IMAP、HTTP)
simple mail transfer protocol: SMTP(简单邮件传输协议)
使用TCP在客户端和服务器之间传送报文,端口号为25 直接传输:从发送方服务器到接收方服务器 传输的3个阶段: 握手 传输报文 关闭 命令/响应交互: 命令:ASCII文本 响应:状态码和状态信息 报文必须为7位ASCII码(邮件的内容必须是7位ASCII码的范围,超过是不允许传输的)
邮件发送举例如下图:
说明:
Alice使用用户代理撰写邮件并发送给bob@someschool.edu
Alice的用户代理将邮件发送到她的邮件服务器;邮件放在报文队列中(SMTP)
SMTP的客户端打开到Bob邮件服务器的TCP连接
SMTP客户端通过TCP连接发送Alice的邮件(SMTP)
Bob的邮件服务器将邮件放到Bob的邮箱
Bob调用他的用户代理阅读邮件(POP3、IMAP、HTTP)
- 邮件服务器会周期性扫描队列,隔一段时间将收集的邮件全部发出。(如果每时每刻都处于“待命”状态是很耗能的)
- 可能导致邮件发送失败的原因:
- 网络连接有问题
- 接收方的邮件服务器地址填写错误
- 垃圾邮件过滤
- 如果邮件发送失败,会将该邮件发送给另外一个失败的队列中,隔一段时间后重新发送,若仍失败,则退回该邮件。
SMTP vs HTTP
SMTP
SMTP:推(push)
SMTP使用持久连接
SMTP要求报文(首部和主体)为7位ASCII编码
SMTP服务器使用 CRLF.CRLF决定报文的尾部
SMTP:多个对象包含在一个报文中
HTTP
HTTP:拉(pull)
二者都是ASCII形式的命令/响应交互、状态码
HTTP:每个对象封装在各自的响应报文中
邮件报文格式
SMTP:交换email报文的协议
RFC 822: 文本报文的标准:
首部行:如
To: From: Subject: 与SMTP命令不同 !
主体:
- 报文,只能是ASCII码字符
问题:如果传输的内容包含中文字符,都不在ASCII范围之内。就要对其进行编码(扩展):
MIME:多媒体邮件扩展(multimedia mail extension),RFC 2045, 2056
在报文首部用额外的行申明MIME内容类型
内部的编码采用base64编码格式
使用bsae64,将不在ASCII范围之内的内容进行长扩展,使得其在ASCII范围之内。(大小写英文字母,加号,等号)
邮件访问协议
- SMTP: 传送到接收方的邮件服务器
- 邮件访问协议:从服务器访问邮件(“拉”)
- POP:邮局访问协议(Post Office Protocol)[RFC 1939]
- 用户身份确认 (代理<–>服务器) 并下载
- IMAP:Internet邮件访问协议(Internet Mail Access Protocol)[RFC 1730]
- 相比POP3更多特性 (更复杂,如:远程目录维护;仅仅只下载邮件正文,附件可选择下载,对手机端友好)
- 直接在邮件服务器上处理存储的报文
- HTTP:Hotmail , Yahoo! Mail等
方便
- POP:邮局访问协议(Post Office Protocol)[RFC 1939]
POP3协议
有邮件“download and delete”(下载并删除)模式
有邮件“Download-and-keep”(下载并保留)模式(不同的客户机都可以拷贝邮件)
POP3在会话中是无状态的(不支持远程目录维护)
IMAP协议
- IMAP服务器将每个报文与一个文件夹联系起来
- 允许用户用目录来组织报文
- 允许用户读取报文组件
- IMAP在会话过程中保留用户状态:目录名、报文ID与目录名之间映射
DNS(Domain Name System)
域名解析系统是一个给其他“应用”应用的应用。(提供域名到IP地址的转换)
DNS的必要性:
先明白IP地址的作用:一个是标识,一个是寻址。网络设备都是按照IP地址来工作的,但是这有一个问题,IP地址都是数字(IPv4:4Byte,32bit;IPv6:16Byte,128bit),人很难记忆。人类还是更倾向于使用有意义的字符串来标识Internet上的设备。所以域名解析系统就应运而生:它提供域名到IP地址的转换。
接下来我们要考虑的是DNS如何实现这一功能,即我们需要考虑以下问题:
问题一:如何命名设备?
用有意义的字符串:好记,便于人类用使用 解决一个平面命名的重名问题:层次化命名
问题二:如何完成名字到IP地址的转换?
分布式的数据库维护和响应名字查询(仅由单一设备去维护上亿数量的用户设备的域名解析是不可能的)
问题三:如何维护:增加或者删除一个域,需要在域名系统中做哪些工作?
DNS总体思路和目标
主要思路:
- 分层的、基于域的命名机制
- 若干分布式的数据库完成名字到IP地址的转换
- 运行在UDP之上端口号为53的应用服务
- 核心的Internet功能,但在端系统(边缘)中的应用层实现
主要目标:
实现主机名-IP地址的转换(name/IP translate)
其他目的:
主机别名-规范名字的转换:Host aliasing
规范名字便于管理,主机别名便于访问
邮件服务器别名-邮件服务器的正规名字的转换:Mail server aliasing
负载均衡:Load Distribution
DNS名字空间
DNS域名结构
一个层面命名设备会有很多重名,因而DNS采用层次树状结构的命名方法:
Internet根被划为几百个顶级域(top lever domains,TLD)
通用的(generic):
.com; .edu ; .gov ; .int ; .mil ; .net ; .org; .firm ; .hsop ; .web ; .arts ; .rec ;
国家的(countries):
.cn ; .us ; .nl ; .jp
每个(子)域下面可划分为若干子域(subdomains)
树叶是主机
全世界一共有13个根域名服务器(中国没有)
域名(Domain Name)
- 从本域往上,直到树根(根域名)。中间使用“.”间隔不同的级别
- 域的域名:可以用于表示一个域
- 主机的域名:一个域上的一个主机
域名的管理
- 一个域管理其下的子域(例如:.cn 被划分为 edu.cn ;com.cn )
- 创建一个新的域,必须征得它所属域的同意
域与物理网络无关
域遵从组织界限,而不是物理网络
一个域的主机可以不在一个网络
一个网络的主机不一定在一个域
例如:我在中国的某间教室运行一台主机,而这台主机域名由欧洲的某个服务器维护。
域的划分是逻辑的,而不是物理的
域名-IP地址的转换
前面提到单一域名服务器存在的问题:
- 可靠性问题:单点故障
- 扩展性问题:通信容量
- 维护问题:远距离的集中式数据库
区域(zone):
区域的划分有区域管理者自己决定
将DNS名字空间划分为互不相交的区域,每个区域都是树的一部分
名字服务器:
- 每个区域都有一个权威名字服务器:维护着它所管辖区域的权威信息 (authoritative record)
- 名字服务器允许被放置在区域之外,以保障可靠性
TLD服务器(顶级域服务器)
负责顶级域名(如com, org, net, edu和gov)和所有国家级的顶级域名(如cn, uk, fr, ca, jp)
- Network solutions 公司维护com TLD服务器
- Educause公司维护edu TLD服务器
区域名字服务器维护资源记录
资源记录(resource records)
作用:维护域名-IP地址(其它)的映射关系
位置:Name Server的分布式数据库中RR格式: (domain_name, ttl, type,class,Value)
Domain_name: 域名
TTL: time to live : 生存时间(权威,缓冲记录)
决定了资源记录应当从缓存中删除的时间
Class 类别 :对于Internet,值为IN
Value 值:可以是数字,域名或ASCII串
Type 类别:资源记录的类型
- Type=A:
Name为主机
Value为IP地址 - Type=CNAME:
Name为规范名字的别名(如:www.ibm.com 的规范名字为servereast.backup2.ibm.com)
value 为规范名字 - Type=NS:
Name域名(如foo.com)
Value为该域名的权威服务器的域名 - Type=MX:
Value为name对应的邮件服务器的名字
- Type=A:
DNS工作过程
应用调用解析器(resolver)
解析器作为客户向Local Name Server发出查询报文(封装在UDP段中)
解析器如何知道Local Name Server的IP地址:这是提前配置好的
一台设备上网,必须要具备四个信息:
- 主机的IP地址
- 所在的子网的子网掩码
- Local Name Server
- Default Gateway(默认网关):从当前子网将数据传出其他子网
Name Server返回响应报文(name/ip)
本地域名服务器(Local Name Server)
并不严格属于层次结构
每个ISP (居民区的ISP、公司、大学)都有一 个本地DNS服务器(也称为“默认名字服务器”)
当一个主机发起一个DNS查询时,查询被送到其本地DNS服务器
起着代理的作用,将查询转发到层次结构中
名字解析过程
目标名字在Local Name Server中
情况1:查询的名字在该区域内部
情况2:缓存(cashing)
如果Local Name Server的缓存没有信息
- 递归查询
问题:名字解析负担都放在当前联络的名字服务器上,根服务器的负担太重
为此出现了迭代查询
- 迭代查询
主机cis.poly.edu 想知道 主机 gaia.cs.umass.edu 的IP地址
根(及各级域名)服务器返回的不是查询结果,而是下一个NS的地址
最后由权威名字服务器给出解析结果
当前联络的服务器给出可以联系的服务器的名字
“我不知道这个名字,但可以向这个服务器请求”
DNS协议、报文
如下图所示:
提高性能:缓存
一旦名字服务器学到了一个映射,就将该映射缓存起来
根服务器通常都在本地服务器中缓存着(使得根服务器不用经常被访问)
目的:提高效率
可能存在的问题:如果情况变化,缓存结果和权威资源记录不一致
解决方案:TTL(默认2天)
新增域
在上级域的名字服务器中增加两条记录,指向这个新增的子域的域名和域名服务器的地址
在新增子域的名字服务器上运行名字服务器,负责本域的名字解析: 名字→IP地址
如:在com域中建立一个“Network Utopia”
到注册登记机构注册域名networkutopia.com
需要向该机构提供权威DNS服务器(基本的、和辅助的)的名字和IP地址
登记机构在com TLD服务器中插入两条RR记录:
(networkutopia.com, dns1.networkutopia.com, NS)
(dns1.networkutopia.com, 212.212.212.1, A)
在networkutopia.com的权威服务器中确保有:
用于Web服务器的www.networkuptopia.com的类型为A的记录
用于邮件服务器mail.networkutopia.com的类型为MX的记录
P2P应用
前面介绍过,任何节点即是服务器,又是客户端。
- 没有(或极少)一直运行的服务器
- 任意端系统都可以直接通信
- 利用peer的服务能力
- Peer节点间歇上网,每次IP地址都有可能变化
- 例子:
- 文件分发 (BitTorrent)
- 流媒体(KanKan)
- VoIP (Skype)
P2P文件传输
这一部分我们将C/S模式和P2P模式的文件分发对比来看:
文件分发时间:C/S模式
服务器传输: 都是由服务器发送给peer,服务器必须顺序传输(上载)N个文件拷贝:
- 发送一个copy: F/us
- 发送N个copy: NF/us
客户端: 每个客户端必须下载一个文件拷贝
- dmin = 客户端最小的下载速率
- 下载带宽最小的客户端下载的时间:F/dmin
采用C/S方法将一个F大小的文件分发给N个客户端耗时:
$$D_{C/S} \ge \max(NF/u_s,F/d_{min})$$
- 当客户端数量很少时,影响传输时间的瓶颈是客户端的下载速率;
- 当客户端数量很多时,影响传输时间的瓶颈是服务器端的上载速率。
- 文件分发时间:P2P模式
服务器传输:最少需要上载一份拷贝
- 发送一个拷贝的时间:F/us
客户端: 每个客户端必须下载一个拷贝
- 最小下载带宽客户单耗时:: F/dmin
客户端: 所有客户端总体下载量NF
- 最大上载带宽是:
$$u_s + \sum_{} u_i
$$
- 除了服务器可以上载,其他所有的peer节点都可以上载
采用P2P方法 将一个F大小的文件分发给N个客户端耗时:
$$D_{P2P} \ge \max(F/u_s, F/d_{min}, NF/(u_s + \sum{}u_i))
$$
随着客户端的数量增多,P2P模式的优势就体现出来了:客户端数量越多,较C/S模式节约的时间就越多。
下图比较直观的给出二者的对比:
P2P文件共享的例子:
Alice在其笔记本电脑上运行P2P客户端程序
间歇性地连接到Internet,每次从其ISP得到新的IP地址
请求“双截棍.MP3”
应用程序显示其他有“ 双截棍.MP3” 拷贝的对等方
Alice选择其中一个对等方, 如Bob.
文件从Bob’s PC传送到Alice的笔记本上:HTTP
当Alice下载时,其他用户也可以从Alice处下载
Alice的对等方既是一个Web客户端,也是一个瞬时Web服务器
从以上例子我们会思考,P2P文件共享需要解决以下问题:
- 如何定位所需资源
- 如何处理对等方的加入与离开
可能的方案:
- 集中式目录
- 完全分布式
- 混合体
P2P:集中式目录
最初的“Napster”设计:
当对等方连接时,它告知中心服务器:
- IP地址
- 内容
Alice查询 “双截棍 .MP3”
Alice从Bob处请求文件
集中式目录存在的问题:
- 单点故障
- 性能瓶颈
- 侵犯版权
P2P:查询洪泛(Gnutella)
全分布式(没有中心服务器)
开放文件共享协议
许多Gnutella客户端实现了Gnutella协议(类似HTTP有许多的浏览器)
覆盖网络:图
如果X和Y之间有一个TCP连接,则二者之间存在一条边
所有活动的对等方和边就是覆盖网络
边并不是物理链路
给定一个对等方,通常所连接的节点少于10个
比特洪流(BitTorrent)
Peer如果想参与到文件传输需要加入到“洪流”(指一些Peer节点的列表和它们之间服务与被服务的关系)当中。
以学习小组为例会比较形象的描述文件传输的过程:假设一门课程的内容被分为很多小的知识点,这些知识点被分发在学习小组当中,那么节点与节点之间可以相互通信,共享这些知识点,从而使每个节点都学习到所有的知识点,掌握整门课程内容。
课程内容就是一个大型文件,知识点就是被划分为的一个个块(256KB)。
那么我们开始思考,各个节点如何知晓其他节点需要哪些块呢?
这里就会提出一个概念:bit map。
我们可以用很小的位去标识整个文件中所有块的有无情况:1表示有;0表示无。这样构成一个一一映射的关系。
洪流中的节点会定期互相交换自己的bit map,从而就知晓了其他节点拥有块的情况。
一开始新加入的节点没有任何块,它会随机的访问其他节点获取块,当获取到四个块之后,就会改变获取策略:优先请求稀缺的块。
简单分析一下这种思想:节点优先获取稀缺的块,从而其他节点就会不断访问该节点,该节点从其他节点不断地获取更好的服务,同时也可以向其他节点提供更好的服务。
文件被分为一个个块256KB
网络中的这些peers发送接收文件块,相互服务
tracker:跟踪torrent中参与节点
Torrent(洪流): 节点的组,之间交换文件块
例:Alice加入到网络中,首先需要从从跟踪服务器处获得peer节点列表, 然后开始和torrent中的peer节点交换块。
Peer如何加入torrent:
- 一开始没有块,但是将会通过其他节点处累积文件块
- 向跟踪服务器注册,获得peer节点列表,和部分peer节点构成邻居关系 (“连接 ”)
- 当peer下载时,该peer可以同时向其他节点提供上载服务
- Peer可能会变换用于交换块的peer节点
- 扰动churn: peer节点可能会上线或者下线
- 一旦一个peer拥有整个文件,它会(自私的)离开或者保留(利他主义)在torrent中
请求块
- 在任何给定时间,不同peer节点拥有一个文件块的子集
- 周期性的,Alice节点向邻居询问他们拥有哪些块的信息
- Alice向peer节点请求它希望的块,稀缺的块
发送块(一报还一报 tit-for-tat)
Alice向4个peer发送块,这些块向它自己提供最大带宽的服务
- 其他peer被Alice阻塞 (将不会从Alice处获得服务)
- 每10秒重新评估一次:前4位
每个30秒:随机选择其他peer节点,向这个节点发送块
- “优化疏通” 这个节点
- 新选择的节点可以加入这个top 4
第三章:计算机网络|传输层
概述和传输层服务
传输层为运行在不同主机上的应用进程提供逻辑通信服务(以报文为单位)。
提供进程-进程之间的通信
传输协议运行在端系统中:
- 发送方:将应用层的报文分成报文段(添加段头,形成本层数据单元),然后传递给网络层。
- 接收方:将报文段重组成报文(去掉段的头部信息,取出段的内容),然后以字节流的形式传递给应用层
传输层向上层提供多种协议:
- Internet: TCP和UDP
传输层VS网络层
网络层服务:主机之间的逻辑通信。
传输层服务:进程间的逻辑通信。(主机之间服务的细分)
依赖于网络层的服务:延时、带宽。
对网络层的服务进行增强:数据丢失、顺序混乱、加密。
有些服务是不可以加强的:带宽、延迟。
传输层向上层提供的服务其中很重要的一个功能就是 复用 (源端)以及解复用(目标端)。(后文详细介绍)
下面举个例子来说明传输层的服务:
假设Ann家与Bill家各有12个小孩,定期,各家的12个小孩会向对方家的12个小孩进行书信往来。那么一次单向通信就需要12×12=144封信件。现在假定是Ann家的孩子们向Bill家的孩子们发送信件。但是一封一封的发送过于繁琐,孩子们会这样解决问题:由Ann家的老大将信件全部收集起来,打包一起发送到Bill家。Bill家的老大收到信件后就会分发给不同的孩子。
在这个例子中:
- 两个家庭 = 于两个主机
- 每个小孩 = 不同的进程
- 信封中的信件 = 应用层报文
- Ann和Bill = 传输协议:
- Ann将信件打包的过程(聚合) = 复用
- Bill将打包的信件分发(拆分) = 解复用
- 送信的邮件服务 = 网络层协议
Internet传输层协议:
TCP:可靠的、保序的传输(提供字节流的服务)
- 多路复用、解复用
- 拥塞控制
- 流量控制
- 建立连接
UDP:不可靠、不保序的传输(提供数据报的服务)
- 多路复用、解复用
- 没有为尽力而为的IP服务添加更多的其它额外服务
二者都是在IP提供的服务的基础之上提供服务(IP提供的服务:best effort)
二者都不能提供的服务:
- 延时保证
- 带宽保证
多路复用与解复用
我们已经知道,IP向传输层提供的提供的服务是主机-主机的,而传输层提供的服务是进程-进程的,如何在传输层实现这一细分的服务的实现,所依靠的就是端口号。
此外:引入Socket的目的就是使层间传递的数据尽可能少。
TCP和UDP都分别有各自的端口号,但二者使用端口的方式并不一样。
先来描述述一下多路复用/解复用的概念:
- 在发送方主机多路复用:
从多个套接字接收来自多个进程的报文,根据套接字对应的IP地址和端口号等信息对报文段用头部加以封装 (该头部信息用于以后的解复用)
- 在接收方主机多路解复用:
根据报文段的头部信息中的IP地址和端口号将接收到的报文段发给正确的套接字(和对应的应用进程)
TCP的多路复用/解复用
之前我们介绍过,TCP的Socket和四元组相捆绑,代表两个进程之间的会话关系。
四元组包含:源端IP,源端进程端口;目标端IP,目标端进程端口。
发送方复用:
- 应用层将进程的信息向传输层传递,其中包含两个部分:Socket和Message。
- Socket包含源端进程端口以及目标端进程端口,这时就会将这两个端口封装在报文段(Segment)中(这里还会封装一些其他信息,我们先不考虑)。段以及源端IP和目标端IP再向下层网络层传输。
- 网络层接收来自上层的段以及IP信息,并进行封装。由此便可以借助下层提供的服务将其传输道目标主机。
接收方解复用:
- 网络层接收到传输来的分组,把头部信息去掉,剩下的段的部分交给传输层。
- 传输层得到段可以通过头部信息知道源端IP、源端进程端口、目标端IP以及目标端进程端口。并可以将信息继续向应用层传递,交给对应的进程。
补充:
服务器能够在一个TCP端口上同时支持多个TCP套接字。
Web服务器对每个连接客户端有不同的套接字。
UDP的多路复用/解复用
UDP的Socket和二元组相捆绑。
二元组包含:本地IP,本地进程端口。
发送方复用:
- 应用层将Message、Socket与目标IP和目标进程端口向传输层传递(注意UDP Socket同TCP不同,不包含目标IP与目标进程端口)。
- 传输层将源进程端口以及目标进程端口封装在头部,形成报文段,向网络层传递。
- 网络层继续将源IP和目标IP封装起来形成数据报(datagram),并借助下层提供的服务将其传输道目标主机。
接收方解复用:
- 网络层接收到传来的数据报,把头部信息去掉,将报文段以及目标IP和目标进程端口向传输层传递。
- 传输层接收下层传来的信息,继续解封装,将数据向应用层传递,交给对应的进程。
补充:
传输层TCP/UDP报文段格式:
对于UDP的多路解复用:如果两个不同源IP地址/源端口号的数据报,但是有相同的目标IP地址和端口号,则被定位到相同的UDP套接字,发给同一个应用进程。(这点同TCP不一样)
因此可以这样记忆:不管是TCP四元组还是UDP二元组,必须元组内信息全部一致,才会对应同一个Socket,发送给同一个进程。
无连接传输:UDP
UDP在IP提供的服务之上并没有增加过多的额外的服务,仅增加了多路复用/解复用。因此UDP也是“尽力而为”的服务。并可能发生如下问题:
- 数据丢失
- 送到应用进程的报文段乱序
UDP的另一个特征就是无连接:
- UDP发送端和接收端之间没有握手
- 每个UDP报文段都被独立地处理
UDP被用于:
- 流媒体(丢失不敏感,速率敏感、应用可控制传输速率)
- 事务性的应用(仅一次通信)
- DNS
- SNMP(简单的网络管理协议)
如果想使用UDP协议,同时又希望具有可靠性,那么这种可靠性服务只能由进程本身(应用层)提供。可以应用特定的差错恢复。
UDP报文段格式:
头部为8Byte,包括:源端口号、目标端口号、长度(包括头部在内的整个报文段的长度)、校验和(checksum)。(均为2Byte)
UDP存在的必要性:
- 不建立连接 (会增加延时)。
- 简单:在发送端和接收端没有连接状态(服务器无需维护客户端状态,客户端也无需维护与源端某一进程的通讯状态)。
- 报文段的头部很小(开销小)。因此一个报文段的载荷(应用程序数据)就比较大。
- 无拥塞控制和流量控制:UDP可以尽可能快的发送报文段。
UDP校验和
校验和的目的:检测在被传输报文段中的差错 (如比特反转)。
发送方:
- 将报文段的内容视为16bit的整数
- 校验和:报文段的加法和(1的补运算)
- 发送方将校验和放在UDP的校验和字段
接受方:
- 计算接收到的报文段的校验和
- 检查计算出的校验和与校验和字段的内容是否相等:
- 不相等——检测到差错(一定错)
- 相等——一种情况是没有差错;另一种情况也许会出现残存错误。
校验和的具体实现:
将报文段的数据(包含一些头部信息),拆分成16bit一组(不足的补零)。将这些16bit的整数相加。
- 进位回滚:
16bit整数相加可能会有进位,这是就把进位加到计算结果的最后一位。最后求得的校验和是处理进位的结果的反码。
目标端重复发送方一样的操作,但是没有最后的取反码的步骤,将其计算出的结果同发送方的检验和相加,如果没有差错,应该是16位“1”(=1111111111111111),否则没有通过校验。
可靠数据传输的原理
可靠数据传输(Reliable data transfer,rdt)在应用层、传输层和数据链路层都很重要。
可靠数据传输的原理
rdt需要提供的是可靠的服务(在上层),可是它却要依赖与下层不可靠的udt服务(可能会丢失、可能会乱序),所以下层信道的不可靠特点决定了可靠数据传输协议( rdt )的。
- **rdt_send()和deliver_data()**是传输层与应用层的层间接口;
- **udt_send()和rdt_rcv()**是传输层与网络层的层间接口。
下面我们来具体讲述传输层是如何实现可靠传输机制的。
在展开讲述之前先提前做个铺垫,如何渐进式地描述这一问题:
先假设底层信道传输是可靠的(实际上并非如此),那么上层就不需要任何机制就可以保证可靠传输,于是我们会将下层的可靠性一点一点剥落,同样的上层就会相应地增加可靠传输机制。这便是接下来的讲解思路。
虽然信息传输是双向流动的,但是我们可以只考虑单向数据传输。(双向的数据传输问题实际上是2个单向数据传输问题的综合)
使用有限状态机 (FSM) 来描述发送方和接收方:
FSM(有限状态机):实际上就是描述协议工作机制的形式化的描述方案。
节点代表状态;边代表节点状态之间的迁移;边上的标记(label):分母代表事件、分子代表采取的动作。
rdt1.0:在可靠信道上的可靠数据传输
首先假设信道传输:
- 没有比特出错
- 没有分组丢失
发送方:
- 应用层将数据传送下来
- 传输层只做两件事情:
- 添加头部信息,封装为包(packet)
- 借助于下层的服务将数据发送出去
接收方:
- 等待下层传来的数据
- 传输层依旧只做两件事:
- 解封装
- 将数据向上层传递
rdt1.0的FSM描述:
rdt2.0:具有比特差错的信道
假设下层信道传输可能出现比特翻转(比特差错)
解决方案就是采用上文提到过的校验和。
发送方在向接收方发送数据时,会采用校验和来判断数据传输有无差错,并且接收方会有一个反馈机制:
- 确认(ACK):如果通过了校验和,接收方会发送ACK信息,显式地告诉发送方分组已被正确接收。
- 否定确认( NAK):如果未通过校验和,接收方会发送NAK信息,显式地告诉发送方分组发生了差错。接着发送方会重新发送分组。
发送方会有一个缓存,以便发送分组失败后可以重新将分组发送给接收方。
发送方:
- 接收来自上层的数据
- 计算校验和并封装为packet;借助下层的服务将数据发送出去
- 转变为等待ACK/NAK的状态:
- 如果接收到NAK信息,重新发送packet,并继续维持等待状态
- 如果接收到ACK信息,转为接收上层信息并发送数据的状态
接收方:
- 接收下层传来的packet,并计算校验和:
- 如果通过(未腐败的(notcorrupt))校验和,解封装,将数据向上层传递,向并发送方发送ACK确认信息
- 如果为通过(腐败的(corrupt))校验和,则向发送方发送NAK信息
rdt2.0的FSM描述:
rdt2.1:停止等待协议
停等协议:发送方发送一个分组,然后等待接收方的应答。(一次只发送一个等待确认信息)
我们仔细思考就会察觉,rdt2.0有一个致命的错误:如果接收方的反馈信息(ACK/NAK)发生了差错该如何处理?
理想很丰满,现实很骨感。接受方说:“正确收到”,那么发送方继续传送下一个包;接收方说:“发生错误”,则发送方重新传包。就怕接收方来了一句:“歪比巴卜”,这就容易给发送方整懵了。
所以说rdt2.0的协议机制并不完备。
为此引入新的机制:序号(sequence number)
停等协议由于一次只发送一个等待确认的信息,因此只需要一位就可以识别(0、1)排序。
发送方:
- 会在每一个分组中添加序号(P0、P1)
- 如果发送方接收到的反馈信息出错(无法识别),无论是ACK还是NAK,发送方都会重新发送旧的分组。
接收方:
- 如果是NAK出错,那么正好接收来重新传送的分组,如果通过校验,发送ACK确认信息;否则发送NAK。
- 如果是ACK出错,那么这时接收方就会收到重复的分组,由于分组增添了序号,那么接收方会将该分组丢掉,不再向上层传递。接着会向发送方发送ACK确认信息,以请求发送后续分组。
rdt2.1的FSM描述:
发送方处理出错的ACK/NAK
接收方处理出错的ACK/NAK
注意:
rdt2.1中,接收方并不知道发送方是否正确收到了其ACK/NAK信息(没有安排确认的确认)。
那考虑是否在发送方安排确认的确认机制呢?那么如此我们如何判断确认的确认是否正确。所以事实上这样的“套娃”设计意义并不大,并不能完美的解决问题。
rdt2.2:无NAK的协议
功能同rdt2.1,但只使用ACK(ack需要编号)
接收方对最后正确接收的分组发ACK,以替代NAK。
接收方必须显式地包含被正确接收分组的序号。 用情商课堂的方式理解很简单:当发送方发送了编号为1的分组(这时它应该等待ACK1) - 低情商:接收方发来了NAK信息→1号分组出错了 - 高情商:接收方发来了ACK0→1号分组出错了 因此对ACK的编号可以替代NAK。
这就为之后的流水线协议做好了基础(一次发送多个数据单位)。
- 使用对前一个数据单位的ACK,代替本数据单位的NAK
- 这样可以使确认信息减少一半,协议处理简单
当然如果ACK信息发送错误依然有可能导致接收方接收分组重复,解决方案仍和rdt2.1是一样的:
rdt2.2的FSM描述(部分):
rdt3.0:具有比特差错和分组丢失的信道
假设下层的传输信道除了比特差错之外还可能丢失分组。
如果出现了分组丢失的情况:一方面接收方在等待分组,另一方面发送方在等待确认信息。所以会出现死锁的情况。(rdt2.2还无法处理这种情况)
所以会引入新的机制:超时重传
需要countdown timer(倒计时定时器)
发送方会等待ACK信息一段合理的时间,如果在这段时间内没有收到ACK信息,就会重新传输分组(一旦超时,发送方就会认为分组已经丢失)。
合理的时间:
传输层timeout时间是适应式的
链路层的timeout时间确定的
接下来会有新的问题:如果只是发送方的ACK信息丢失,或者只是分组(或ACK信息)被延时,那么就会导致接收方收到的分组重复。这个问题在rdt2.1中就已经解决。
rdt3.0的FSM描述(发送方):
rdt3.0的运行:
过早超时(延迟的ACK)也能够正常工作;但是效率较低,一半的分组和确认是重复的(超时之后的分组和ACK都是发送两次的);
因此设置一个合理的超时时间也是比较重要的。
rdt3.0的性能:
rdt3.0可以工作(功能比较完备),但链路容量比较大的情况下,性能很差。
链路容量比较大,一次发一个PDU 的不能够充分利用链路的传输能力。
举个例子:A地到B地相距甚远,驱车从A地到B地需要很长的时间,但是停等协议只允许高速公路上一次跑一辆汽车(实际上高速公路可以容纳很多车辆)。所以链路越大,停等协议对链路的利用率就越低。
即:网络协议限制了物理资源的利用。
具体可以举例计算(如下图):
流水线协议(Pipelined protocols)
为了提高链路利用率,接下来就引入了流水线的方式。
上文提到造成链路利用率低下的原因是停等协议每次只允许发送一个分组,那么我们就可以考虑一次发送多个分组以提高利用率,但是这个值并不会增加到100%,随着能够同时发送分组的数量的增加,到了后期瓶颈就由停等协议转移到了链路带宽。
流水线协议:允许发送方在未得到对方确认的情况下一次发送多个分组。
必须增加序号的范围:用多个bit表示分组的序号
在发送方/接收方要有缓冲区:
发送方缓存:未得到确认,可能需要重传;
接收方缓存:上层用户取用数据的速率 ≠ 接收到的数据速率;接收到的数据可能乱序,排序交付(可靠)
有两种通用的流水线协议:
Go-back-N:回退N(GBN)
Selective Repeat:选择重传(SR)
在介绍以上两种协议时我们先做一些铺垫,先来介绍一个通用协议:滑动窗口(slide window)协议
该协议根据发送方以及接收方窗口大小的不同可以分为:
停止等待协议:send_window = 1, receive_window = 1
回退N协议:send_window > 1,receive_window = 1
选择重传协议:send_window > 1,receive_window > 1
发送方窗口(send_window)大于1的协议我们就称之为流水线协议。
发送缓冲区:
形式:内存中的一个区域,落入缓冲区的分组可以发送
功能:用于存放已发送,但是没有得到确认的分组
必要性:需要重发时可用
发送缓冲区的大小:一次最多可以发送多少个未经确认的分组
停止等待协议 = 1
流水线协议 > 1,合理的值,不能很大,链路利用率不能够超100%
发送缓冲区中的分组:
未发送的:落入发送缓冲区的分组,可以连续发送出去;
已经发送出去的、等待对方确认的分组:发送缓冲区的分组只有得到确认才能删除
发送窗口:
指的是发送缓冲区的一个范围(是发送缓冲区的一个子集)。
存放已发送但是未确认的分组。(实际上发送传窗口是那些已发送但是未经确认分组的序号构成的空间)
发送窗口的最大值 ≤ 发送缓冲区的值
发送窗口的滑动过程:
一开始:没有发送任何一个分组
后沿 = 前沿
之间为发送窗口的尺寸 = 0
发送窗口的移动:前沿移动
每发送一个分组,前沿前移一个单位
发送窗口前沿移动的极限:不能够超过发送缓冲区
注意:绿色部分为发送缓冲区
发送窗口的移动:后沿移动
后沿移动的条件:收到老分组(后沿)的确认
结果:发送缓冲区罩住新的分组,来了分组可以发送
后沿移动的极限:不能够超过前沿
接收窗口:
接收窗口 (receiving window) = 接收缓冲区
接收窗口用于控制哪些分组可以接收:
只有收到的分组序号落入接收窗口内才允许接收
若序号在接收窗口之外,则丢弃
接收窗口尺寸 Wr = 1,则只能顺序接收
举例:
Wr=1,在0的位置;只有0号分组可以接收
向前滑动一个,罩在1的位置,如果来了第2号分组,则丢弃
接收窗口尺寸 Wr > 1 ,则可以乱序接收(但提交给上层的分组,要按序提交)
滑动:
低序号的分组到来(按序),接收窗口移动;
高序号分组乱序到,缓存但不交付(因为要实现rdt,不允许失序),不滑动
发送确认:
接收窗口尺寸 = 1 ; 发送连续收到的最大的分组确认(累计确认)
接收窗口尺寸 > 1 ; 收到哪个分组,就发送那个分组的确认(非累计确认)
绿色区域表示可接收的分组。
正常情况下两个窗口的互动:
发送窗口:
有新的分组落入发送缓冲区范围,发送 → 前沿滑动
来了老的低序号分组的确认 → 后沿向前滑动 → 新的分组可以落入发送缓冲区的范围
接收窗口:
收到分组,落入到接收窗口范围内,接收
发送确认给发送方
如果低序号分组确认收到,向前滑动接收窗口
否则不滑动
异常情况下GBN的两窗口互动:
发送窗口:
新分组落入发送缓冲区范围,发送 → 前沿滑动
超时重发机制让发送端将发送窗口中的所有分组发送出去(低序号开始的连续的已发送但未确认的分组全部重新发送)
来了老分组的重复确认 → 后沿不向前滑动 → 新的分组无法落入发送缓冲区的范围(此时如果发送缓冲区有新的分组可以发送)
接收窗口:
收到乱序分组,没有落入到接收窗口范围内,抛弃
(重复)发送老分组的确认,累计确认
异常情况下SR的两窗口互动:
发送窗口:
新分组落入发送缓冲区范围,发送 → 前沿滑动
超时重发机制让发送端将超时的分组重新发送出去
来了乱序分组的确认 → 后沿不向前滑动 → 新的分组无法落入发送缓冲区的范围(此时如果发送缓冲区有新的分组可以发送)
接收窗口:
收到乱序分组,落入到接收窗口范围内,接收
发送该分组的确认,单独确认
由此我们小结一下GBN协议和SR协议的异同:
相同点:
发送窗口 > 1
一次能够可发送多个未经确认的分组
不同点:
GBN :接收窗口尺寸 = 1
接收端:只能顺序接收
发送端:从表现来看,一旦一个分组没有发成功,如:0、1、2、3、4; 假如1未成功,2、3、4都发送出去 了,要返回1再发送1、2、3、4。
累计确认:cumulative ack
发送端拥有对最老的未确认分组的定时器:
只需设置一个定时器
当定时器到时时,重传所有未确认分组
发送窗口的最大值(序号大小为n):2n-1
SR: 接收窗口尺寸 > 1
接收端:可以乱序接收
发送端:发送0、1、2、3、4,一旦1未成功,2、3、4,已发送,无需重发,只选择性发送1。
非累计确认/独立确认:individual ack
发送方为每个未确认的分组保持一个定时器:
当超时定时器到时,只是重发到时的未确认分组
发送窗口的最大值(序号大小为n):2n-1
列出下表对比一下GBN协议和SR协议:
GBN
SR
优点
简单,所需资源少(接收方一个缓存单元)
出错时,重传一个代价小
缺点
一旦出错,回退N步代价大
复杂,所需要资源多(接收方多个缓存单元)
适用范围:
出错率低:比较适合GBN,出错非常罕见,没有必要用复杂的SR,为罕见的事件做日常的准备和复杂处理
链路容量大(延迟大、带宽大):比较适合SR而不是GBN,一旦出错代价太大
面向连接的传输:TCP
TCP概述
点对点:一个发送方,一个接收方
可靠的、按顺序的字节流:没有报文边界
TCP不提供报文界限:发送方可能发送两个报文,接收方可能会收到一个大的报文,也可能收到四个小的报文。应用进程之间报文的界限需要应用进程自己去维护。
提供管道化(流水线)的协议:
TCP拥塞控制和流量控制设置窗口大小
发送和接收有缓存
全双工数据:
在同一连接中数据流双向流动(一方进程可同时发送数据和接收数据)
面向连接:在数据交换之前,通过握手(交换控制报文) 初始化发送方、接收方的状态变量
有流量控制:发送方不会淹没接收方
MSS:最大报文段大小
MTU:最大传输单元
TCP报文段结构
说明:
源端口号、目标端口号:16bit
序号并不是报文段的序号,而是报文段的数据载荷(body)部分的第一个字节在整个字节流中的偏移量。(对字节计数)
一般情况下序号并不是从0或1这样固定的序号开始:为了避免长时间滞留在网络中的分组所包括的段对新的连接造成影响。
确认号:依然是字节计数
如果接收方传来的ACK为555,则表示接收方已经接收到了554及之前所有的字节,并希望发送方下一个传来555字节的数据。(累计确认)
接收方处理乱序的报文段:可以缓存,也可以丢弃。
首部长度:4个字节为单位,表示该TCP段的首部数据大小。
RSF(RST、SYN、FIN)标志位:主要是用于两个应用进程进行TCP连接的标志位。
不同标志位的组合代表不同的握手(后面会提到),以及连接释放请求、确认等。
接受窗口:用于流量控制。如果接收方的接收窗口为X,则表示接收方可以接收X字节的数据。
校验和:同UDP中的校验和作用一致。
TCP确认号和序号实例:
TCP往返延时(RTT)和超时
分析可能的情况:TCP超时应该设置的比RTT长。如果设置太短,就会发生没必要的重传;如果太长,那么对报文段丢失的反应太慢。但是RTT是在不断变化的,因此我们需要定期测量RTT。
SampleRTT:测量从报文段发出到收到确认的时间。
仅用当前的SampleRTT是不合理的,应该对几个最近的测量值求平均。
具体公式如下:
EstimatedRTT = (1- α) × EstimatedRTT + α × SampleRTT
指数加权移动平均
过去样本的影响呈指数衰减
推荐值:α = 0.125
进一步我们需要考虑EstimatedRTT的变化范围:
EstimtedRTT + 安全边界时间
EstimatedRTT变化大 (方差大) → 较大的安全边界时间
SampleRTT会偏离EstimatedRTT多远:
DevRTT = (1-β) × DevRTT + β × |SampleRTT-EstimatedRTT|
(推荐值:β = 0.25)
由此我们可以计算超时时间间隔:
TimeoutInterval = EstimatedRTT + 4 × DevRTT
TCP的可靠数据传输(rdt)
TCP在IP不可靠服务的基础上建立了rdt
管道化的报文段:GBN or SR(TCP是两种的混合)
累积确认(像GBN)
设置单个重传定时器(像GBN)
是否可以接受乱序的,TCP没有规范。可以缓存乱序报文段,也可以丢弃。
通过以下事件触发重传:
超时(只重发那个最早的未确认段:SR)
重复的(三次冗余)确认:
例子:收到了ACK50,之后又收到3个ACK50
在分析TCP如何建立rdt,我们依旧采取以上讲可靠数据传输原理的流程,一步一步增加功能。
TCP发送方
首先考虑简化的TCP发送方:
忽略重复的确认
忽略流量控制和拥塞控制
TCP发送方事件:
从应用层接收数据:
用nextseq创建报文段
序号nextseq为报文段首字节的字节流编号
如果还没有运行,启动定时器
定时器与最早未确认的报文段关联
超时:
重传后沿最老的报文段
重新启动定时器
收到确认:
如果是对尚未确认的报文段确认
更新已被确认的报文序号
如果当前还有未被确认的报文段,重新启动定时器
TCP重传(左图为ACK丢失,右图为ACK超时):
(下图为累计确认)
在RFC中对产生TCP ACK的建议(如下表)
接收方的事件
TCP接收方动作
所期望序号的报文段按序到达。 所有在期望序号之前的数据都已经被确认
延迟的ACK。对另一个按序报文段的到达最多等待500ms。如果下一个报文段在这个时间间隔内没有到达,则发送一个ACK。
有期望序号的报文段到达。另一个按序报文段等待发送ACK(接收到连续的两个段)
立即发送单个累积ACK,以确认两个按序报文段。
比期望序号大的报文段乱序到达。检测出数据流中的间隔
立即发送重复的ACK,指明下一个期待字节的序号
能部分或完全填充接收数据间隔的报文段到达。
若该报文段起始于间隔(gap)的低端,则立即发送ACK。
快速重传
产生快速重传的原因:超时周期往往太长(在重传丢失报文段之前的延时太长)。
快速重传:在定时器过时之前重发报文段
由三个冗余ACK触发
它假设跟在被确认的数据后面的数据丢失了:
第一个ACK是正常的;
收到第2个该段的ACK,表示接收方收到一个该段后的乱序段;
收到第3,4个该段的ack,表示接收方收到该段之后的2个 ,3个乱序段,可能性非常大段丢失了
如果发送方收到同一数据 的3个冗余ACK,重传最小序号的段。
TCP流量控制
流量控制:接收方控制发送方,不让发送方发送的太多、太快以至于让接收方的缓冲区溢出。
接收方在其向发送方的TCP段头部的rwnd字段“通告”其空闲buffer大小
RcvBuffer大小通过socket选项设置 (典型默认大小为4096 字节)
很多操作系统自动调整 RcvBuffer
发送方限制未确认(“inflight”)字节的个数 ≤ 接收方发送过来的rwnd值
保证接收方不会被淹没
连接管理
在正式交换数据之前,发送方和接收方握手建立通信关系:
同意建立连接(每一方都知道对方愿意建立连接)
同意连接参数(准备、初始化资源)
建立连接
首先考虑2次握手总是可行的吗?(仅一方发送连接请求,另一方收到后发送连接确认)
有很多因素会导致2次握手的失败:
变化的延迟(连接请求的段没有丢,但可能超时)
由于丢失造成的重传 (e.g. req_conn(x))
报文乱序
相互看不到对方
2次握手的失败场景:
说明
在客户端接收服务器发来的连接确认之前定时器到时,那么客户端就会再发送一条新的连接建立请求,如此服务器会消耗资源去维护许多不必要的“半连接”。
数据超时会导致服务器将老数据按照新的数据处理。
所以2次握手是不可取的,由此引入了3次握手。
SYNbit = 1 表示建立连接请求
3次握手可以有效地解决半连接和接收老数据的问题
3次握手的FSM表示:
关闭连接
客户端,服务器分别关闭它自己这一侧的连接
发送FIN bit = 1的TCP段
一旦接收到FIN,用ACK回应
接到FIN段,ACK可以和它自己发出的FIN段一起发送
可以处理同时的FIN交换
这样的连接拆除方式并不完美:
会存在一方拆除连接,另一方还维持连接的情况。
拥塞控制原理
拥塞的非正式定义: “太多的数据需要网络传输,超过了网络的处理能力。”
拥塞控制与流量控制不同:拥塞控制指的是网络的问题,流量控制指的是接收方的问题。
拥塞的表现:
分组丢失 (路由器缓冲区溢出)
分组经历比较长的延迟(在路由器的队列中排队)
拥塞是网络中前10位的问题
产生拥塞的原因/代价
场景一:
2个发送端,2个接收端
一个路由器,具备无限大的缓冲
输出链路带宽:R
没有重传
如左图:当λin逐渐增加时,λout也在增加,当λin达到R/2时,λout达到最大值,也就是说每个连接的最大吞吐量为R/2。
如右图:从延迟的角度看,当进入的速率λin接近链路链路带宽R时,延迟陡增。
场景二:
一个路由器,有限的缓冲
分组丢失时,发送端重传
应用层的输入=应用层输出:λin = λout
传输层的输入包括重传:λin ≥ λout
理想化场景:发送端有完美的信息,即发送端知道什么时候路由器的缓冲是可用的。
只在缓冲可用时发送
不会丢失:λ’in = λin
这样情况依然同上:
但是这样的代价很大:每个路由器都需要告知发送方自己的空闲缓冲区有多大,不好实现。
理想化场景二:掌握丢失信息。即分组可以丢失,在路由器由于缓冲器满而被丢弃。
如果知道分组丢失了,发 送方重传分组
会丢失:λ’in > λin
分析:这样一来,为了让λout逼近于R/2,就需要让λ’in比既定的输出要大(因为存在分组丢失)。
重传的丢失分组
没有必要重传的重复分组
代价:
为了达到一个有效输出,网络需要做更多的工作(重传)
没有必要的重传,链路中包括了多个分组的拷贝(超时)
是那些没有丢失,经历的时间比较长(拥塞状态)但是超时的分组
因为网络拥塞而导致接收效率降低,而为了提高接收效率,就会增加发送量,如此一来会加剧网络拥塞,如果不加以控制,那么网络最终会瘫痪。这也是拥塞的特性。
场景三:
4个发送端
多重路径
超时/重传
从宏观上来看,各方都不停地向网络中发送数据,就会发生网络拥塞的一个极致:整个网络出现死锁的情况
代价:当分组丢失时,任何“关于这个分组的上游传输能力” 都被浪费了。
拥塞控制方法
端到端拥塞控制:
没有来自网络的显式反馈
端系统根据延迟和丢失事件推断是否有拥塞
TCP采用此方法
网络辅助的拥塞控制:
路由器提供给端系统以反馈信息
单个bit置位,显示有拥塞 (SNA, DECbit,TCP/IP ECN, ATM)
显式提供发送端可以采用的速率
首先来了解网络辅助的拥塞控制,以 ATM ABR 拥塞控制为例
ABR: available bit rate: ATM网络的其中一个模式
“弹性服务”
如果发送端的路径“轻载 ”
发送方尽可能使用可用带宽
如果发送方的路径拥塞了:
发送方限制其发送的速度到一个最小保障速率上
RM (资源管理) 信元:
由发送端发送,在数据信元中间隔插入
RM信元中的比特被交换机设置 (“网络辅助”)
NI bit: no increase in rate (轻微拥塞)速率不要增加了
CI bit: congestion indication 拥塞指示
发送端发送的RM 信元被接收端返回, 接收端不做任何改变
在RM信元中的2个字节 ER (explicit rate)字段
拥塞的交换机可能会降低信元中ER的值
发送端发送速度因此是最低的可支持速率
数据信元中的EFCI bit: 被拥塞的交换机设置成1
如果在管理信元RM前面的数据信元EFCI被设置成了1, 接收端在返回的RM信元中设置CI bit
TCP拥塞控制
TCP采用端到端的拥塞控制。
端到端的拥塞控制机制:
路由器不向主机有关拥塞的反馈信息
路由器的负担较轻
符合网络核心简单的TCP/IP架构原则(复杂性放在网络边缘,传输层及以上)
端系统根据自身得到的信息,判断是否发生拥塞,从而采取动作
拥塞控制的几个问题:
如何检测拥塞:
轻微拥塞
拥塞
控制策略:
在拥塞发送时如何动作,降低速率
轻微拥塞,如何降低
拥塞时,如何降低
在拥塞缓解时如何动作,增加速率
拥塞感知
某个段超时了(丢失事件 ):拥塞
超时时间到,某个段的确认没有来
原因1:网络拥塞(某个路由器缓冲区没空间了,被丢弃),概率大
原因2:出错被丢弃了(各级错误,没有通过校验,被丢弃),概率小
一旦超时,就认为拥塞了,有一定误判,但是总体控制方向是对的
有关某个段的3次重复ACK:轻微拥塞(如下图)
段的第1个ack,正常,确认绿段,期待红段
段的第2个重复ack,意味着红段的后一段收到了,蓝段乱序到达
段的第2、3、4个ack重复,意味着红段的后第2、3、4个段收到了,橙段乱序到达,同时红段丢失的可能性很大(后面3个段都到了,红段都没到)
网络这时还能够进行一定程度的传输,拥塞但情况要比第一种好
速率控制方法
维持一个拥塞窗口的值:CongWin
发送端限制已发送但是未确认的数据量(的上限):
LastByteSent - LastByteAcked ≤ CongWin
从而粗略地控制发送方的往网络中注入的速率(如下公式):
$$rate ≈ \frac{ConWin}{RTT} bytes/sec
$$
CongWin是动态的,是感知到的网络拥塞程度的函数:
超时或者3个重复ack,CongWin会下降:
超时时:CongWin降为1MSS,进入SS阶段然后再倍增到CongWin/2(每个RTT),从而进入CA阶段
3个重复ack :CongWin降为CongWin/2,CA阶段
如果没有超时:CongWin会上升
SS(慢启动)阶段:加倍增加(每个RTT)
CA(拥塞避免)阶段:线性增加(每个RTT)
联合控制的方法:
TCP拥塞控制和流量控制的联合动作。
发送端控制发送但是未确认的量同时也不能够超过接收窗口,满足流量控制要求:
SendWin = min {CongWin, RecvWin}
同时满足拥塞控制和流量控制要求
TCP拥塞控制策略
慢启动
AIMD:线性增、乘性减少
超时事件后的保守策略
TCP慢启动:
连接刚建立, CongWin = 1 MSS
例如: MSS = 1460bytes & RTT = 200 msec,则初始速率 = 58.4kbps
但是可用带宽可能远大于MSS/RTT,所以应该尽快加速,到达希望的速率
当连接开始时,指数性增加(每个RTT)发送速率直到发生丢失事件
每一个RTT, CongWin加倍
每收到一个ACK时,CongWin加1
慢启动阶段:只要不超时或3个重复ack,一个RTT,CongWin加倍
初始速率很慢,但是加速却是指数性的
AIMD:
乘性减:
丢失事件后将CongWin降为1,将CongWin/2作为阈值,进入慢启动阶段(倍增直到 CongWin/2)
加性增:
当CongWin > 阈值时,一个RTT如没有发生丢失事件 ,将CongWin加1MSS: 探测
策略不同:
当收到3个重复的ACKs:
CongWin 减半
窗口(缓冲区大小)之后线性增长
当超时事件发生时:
CongWin被设置成 1 MSS,进入SS阶段
之后窗口指数增长
增长到一个阈值(上次发生拥塞的窗口的一半)时 ,再线性增加
再次强调一下何时候应该将指数性增长变成线性增长:
在超时之前,当 CongWin变成上次发生超时的窗口的一半时
具体实现:
变量:Threshold
出现丢失,Threshold设置成 CongWin的1/2
小结
事件
状态
TCP 发送端行为
解释
以前没有收到ACK的data被ACKed
慢启动 (SS)
CongWin = CongWin + MSS If (CongWin > Threshold) ,状态变成 “CA”
每一个RTT CongWin 加倍
以前没有收到ACK的data 被ACKed
拥塞避免 (CA)
CongWin = CongWin+MSS × (MSS/CongWin)
加性增加, 每一个RTT对 CongWin 加一个 1 MSS
通过收到3个重复的ACK,发现丢失的事件
SS or CA
Threshold = CongWin/2,CongWin = Threshold+3,状态变成“CA”,
快速重传, 实现乘性的减,CongWin 没有变成1 MSS.
超时
SS or CA
Threshold = CongWin/2,CongWin = 1 MSS,状态变成“SS”
进入slow start
重复的 ACK
SS or CA
对被ACKed 的segment, 增加重复ACK的计数
CongWin and Threshold 不变
TCP吞吐量
使用窗口window尺寸W和RTT来描述TCP的平均吞吐量(忽略慢启动阶段,假设发送端总有数据传输):
W:发生丢失事件时的窗口尺寸(单位:字节)
平均窗口尺寸:3/4W
平均吞吐量:RTT时间吞吐3/4W
$$avg TCPthtuput = \frac{3}{4}\frac{W}{RTT} bytes/sec
$$
TCP公平性
公平性目标: 如果 K个TCP会话分享一个链路带宽为R的瓶颈,每一个会话的有效带宽为 R/K
分析为什么TCP是公平的(2个竞争的TCP会话为例,假设两个会话的RTT相等):
加性增加,斜率为1, 吞吐量增加
乘性减,吞吐量比例减少
(具体省略详细解释,但是这个平衡的过程真的很神奇)
考虑并行TCP连接:
如果带宽为R的链路支持了 9个TCP连接
如果新的应用要求建1个TCP连接,获得带宽R/10
如果新的应用要求建11个TCP 连接,获得带宽R/2