计算机网络(自顶而下方法)第三章——运输层

参考书目:《计算机网络(自顶而下方法)第八版》

参考原文:https://blog.csdn.net/qq_39326472/article/details/88089747

目录

第三章——运输层

3.1  概述和运输层服务

3.2  多路复用与多路分解

3.3  无连接运输:UDP

3.3.1  UDP报文结构

3.3.2  UDP检验和

3.4  可靠数据传输原理

3.4.1  构造可靠数据传输协议

 3.4.2  流水线可靠数据传输协议

3.4.3  回退N步

 3.4.4  选择重传

3.5  面向连接的运输:TCP

3.5.1  TCP连接

3.5.2  TCP报文段结构

3.5.3  往返时间的估计与超时

3.5.4  可靠数据传输

3.5.5  流量控制

3.5.6  TCP连接管理

3.6  拥塞控制原理

 3.6.1  拥塞原因与代价

3.6.2  拥塞控制方法

3.7  TCP拥塞原理

3.7.1  经典的TCP拥塞控制


第三章——运输层

运输层位于应用层和网络层之间,是分层网络体系的重要组成部分,本章将着重讲述运输层的两个协议,即TCP和UDP运输层协议。


3.1  概述和运输层服务

传输层协议为运行在不同端系统上的应用进程之间提供逻辑通信功能。应用层进程使用传输层提供的逻辑通信功能,而无需考虑实现

运输层协议的工作内容:

  • 发送方:把应用数据划分成报文段,交给网络层。
  • 接收方:把报文段重组成应用数据,交付给应用层。

运输层和网络层的区别:

  • 网络层:不同主机间的逻辑通信
  • 运输层:应用进程之间的逻辑通信

类似于快递:

一个寝室的学生要给异地另一个寝室的学生发快递,进程相当于学生,进程间的报文相当于包裹,主机就是寝室,运输协议就是取走快递的快递员张三和把快递送到收件人手中的快递员李四,网络层协议就是物流公司提供的运输服务。

完整流程相当于进程将报文交给运输协议,运输协议再将报文交给网络层协议,网络层协议将报文送到目的地后,目的地运输协议将报文分配到接收方进程。

上例的几种特殊情况:

1.快递员张三和李四生病了,换成了王五和赵六:不同的运输层可能提供不一样的服务。

2.物流公司不承诺信件送达的最长时间:运输层协议能够提供的服务受到底层网络协议的服务模型的制约。

3.物流公司不能保证包裹一定能送达,但是发件人可以在发件时购买保险:网络层不提供某些服务的情况下,运输层自己提供。

4.快递员只在本地活动:运输层协议是在端系统中实现的。

5.快递公司在送快递时不会看快递的物品是什么:路由器不会检查封装在数据报中的传输层报文段的数据。

6.快递员从发件人手里取走快递时会在包裹上贴上标签:传输层协议收到报文后会为其添加传输层首部。

 端口:

  • 端口的作用就是让应用层的各种应用进程都能将数据通过端口向下交付给运输层,以及让运输层知道应当将报文段的数据向上通过端口交付给应用层相应的进程(或者线程)。
  • 端口时用来标志应用层的工具。
  • 端口用一个16bit端口号进行标志。

UDP和TCP简介:

因特网为应用层提供了截然不同的两种传输层协议:UDP(用户数据报协议)它提供一种不可靠、无连接的服务;另一种是TCP,它提供可靠的,面向连接的服务。运输层分组也被称为报文段;

简单了解一下因特网的网络层,网络层协议有一个名字即IP,即网际协议。IP为主机间提供逻辑通信,IP的服务模型为尽力而为交付服务(best-effort delivery service)这意味着IP尽最大的努力在主机间交付报文段,但是不做任何保证,它不保证报文段的交付、不保证报文段按序交付、不保证报文段中数据的完整性,即IP提供一种不可靠的服务。每台主机都需要有一个网络层地址,即IP地址

UDP和TCP最基本的责任就是将IP提供的主机间交付服务扩展到不同端系统上两个个进程之间的服务。这也被称为传输层的多路分解和多路复用。UDP和TCP通过在传输层首部添加差错检查字段来提供完整性检查。进程到进程之间的数据交付差错检查是最低限度的两种传输层服务,也是UDP可以提供的仅有的两种服务,UDP和IP一样,也是不可靠服务。

TCP提供额外的服务,首先它是一种可靠数据服务,这意味着TCP协议保证数据的按序、完整地从发送端应用进程发送到接收端应用进程。TCP通过序号、确认、定时器以及流量控制来将IP的不可靠数据传输转换为可靠数据传输。其次,TCP提供拥塞控制,拥塞控制与其说是一种提供给应用程序的服务,不如说是一种提供给整个网络的服务,因为整个网络都将因为拥塞控制而受益。不太严格地说,拥塞控制力求为每一个经过一条拥塞网络的连接提供平等的共享网络链路带宽,从而避免一条TCP连接用过多的流量来淹没通信主机之间的链路和设备。拥塞控制是通过调节发送进网络的的流量速率来做得到。UDP不提供拥塞控制,使用UDP传输的应用程序可以根据需要以任意的速率发送数据。


3.2  多路复用与多路分解

多路复用与多路分解服务是所有计算机网络都需要的。

一个进程(作为网络应用的一部分)有一个或者多个套接字(socket),它相当于从网络向进程传递数据和从进程向网络中传递数据的门户。 事实上,运输层在传递数据时并没有直接吧数据交付给进程,而是给了中间的套接字。

将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。

在源主机从不同套接字中收集数据块,并封装上首部信息,从而生成报文段,然后将报文段传递到网络层,所有这些工作称为多路复用

简单来说,多路分解就是运输层将数据分散交给各个进程,多路复用就是通过套接字把数据从进程那里收集起来给运输层,套接字相当于信箱,运输层从这里收集“信件”,当收到外来的“信件”时,运输层也会将其放到“信箱”中

每个套接字都有一个唯一的标识符,称为端口号。端口号大小在0-65535之间,其中0-1023属于周知端口号,它们为特定的套接字所拥有。报文段为了让运输层能把自己正确地交到对应的套接字手中,会在首部上包含源端口号目的端口号,交代清楚自己来自哪里,要到哪去。

1.无连接的多路复用与多路分解

需要注意的是,在创建Socket的时候,是由传输层为之分配端口号;一个UDP套接字是由一个目的IP地址和目的端口号即二元组来标志的;如果两个UDP报文段有不同的源IP地址或者源端口号,但是有相同的目的IP和目的端口号的话,它们将通过同一个Socket到达同一个应用程序。

2.有链接的多路复用与多路分解

TCP协议中的Socket是通过一个四元组来标记的(源IP地址,源端口号,目的IP地址,目的端口号),两个具有不同源IP地址或者源端口号,但有相同的目的IP地址和目的端口号的TCP报文段将通过两个不同的Socket进入同一应用进程。这也表示,一个应用进程可以关联多个Socket,而一个Socket将只关联一个应用进程。常常,这样的对应关系是通过线程来实现的:一个进程有多个线程,而每个线程关联了一个Socket,这样做可以提高服务器性能。

实际上,传输层就是根据套接字中的信息来实现多路分解的,而这些信息是在多路复用的时候被放置在报文段中的。


3.3  无连接运输:UDP

功能:进程到进程之间的数据交付(复用/分解服务),少量的差错检查。

UDP的特点:仅仅做了运输协议要求的最低限度的工作,此外,因为在发送报文段之前,发送方和接收方的传输层实体之间没有握手,所以UDP也被称为无连接的。

UDP作用过程:以DNS为例,当主机中的应用程序想要进行一次查询时,它将报文发送给UDP,UDP为报文增加首部字段后交给网络层,网络层将报文封装进一个IP数据报中,尽力而为地发送给一个Name Server,当DNS客户端等待不到对该查询的响应时(有可能网络层将其丢失了)则会向其他Name Server发送查询请求,或者向发送端通知发送失败。

UDP的优势:

  • 关于发送什么数据以及何时发送的应用层控制更加精细:UDP在拿到数据后,会立刻将数据打包到UDP报文段并且立即传递给网络层,但TCP有一个拥塞控制机制,并且为了确保数据的可靠传输往往会不断发送报文直到接收方确认收到,这一流程使得TCP的传输时间变得不可控。
  • 无需连接建立:TCP在开始数据传输前会经过三次握手,而UDP不需要任何准备就能直接开始传输,减少了传输时延,提高了数据传输速度。
  • 无需维护连接状态:TCP为了可靠传输会在传输过程中跟踪大量参数,而UDP不需要维护连接状态,也就不需要跟踪这些参数,因此当应用程序运行在UDP之上时往往能支持更多用户的需求。
  • 分组首部开销小:TCP有20字节的首部开销,而UDP只有8字节。

注意事项:

  1. 虽然UDP没有拥塞控制系统,但是依旧要预防网络进入拥塞状态,因为这会导致很高的丢包率,目前研究人员正在采取新的机制解决这一问题。
  2. 使用UDP也有可能实现可靠的数据传输,但是需要在应用程序自身建立可靠机制来完成。

3.3.1  UDP报文结构

      UDP首部只有4个字段,每个字段由两个字节组成,共8个字节,分别是源端口号,目的端口号,长度,校验和。长度表示包含首部在内的UDP报文段长度。

3.3.2  UDP检验和

      UDP检验和提供了差错检测功能,即检测从发送端到接收端移动时,其中的比特是否发生了改变。具体实施方法是将报文段中所有16比特字(前3个字段)的和进行反码计算,其中求和时溢出的部分要回卷(即将溢出部分加在最低位),将运算结果放在校验和字段。

      在接收端,只需要将4个字段的4个16位比特加在一起,如果没有出现差错,则最后的和应该为1111111111111111,否则出现了差错。

      UDP作为传输层协议,提供的差错检测功能很有可能和底层协议提供的相似功能产生冗余,但是这是必须的,因为由于不能保证源和目的地之间所有链路都提供差错检测功能。即便数据在链路上正确传输,也无法保证其在中间路由器的内存中不发生错误,所以要实现端到端的差错检测,就必须在传输层协议中实现该功能,这一原则在系统设计中被称为端到端原则:“因为某一功能必须在端到端实现,与在较高层次提供这些功能的代价相比,在较低层次上设置的功能可能是冗余的,或者根本是没有用的”。

      简而言之,因为无法保证数据传输时途径的所有部分都能做到差错检测,顶层协议必须要提供这一功能。


3.4  可靠数据传输原理

可靠数据传输为上层实体提供的服务抽象是:数据可以通过一套可靠的信道进行传输,借助于可靠信道,传输数据就不会受到损坏或者丢失;并且所有数据都可以按照其发送顺序进行交付。

实现这种服务抽象的是可靠数据传输协议的责任,但由于可靠数据传输协议的下层协议也许并不可靠,所以这是一项困难的任务。例如TCP协议就是在不可靠的端到端网络上实现的可靠数据传输。

在本节中,我们研究的主体就是可靠的单向数据传输的情况,即数据传输是从发送端到接收端的。


3.4.1  构造可靠数据传输协议

1.经完全可靠信道的可靠数据传输:rdt1.0

这种情况是最简单的,我们假设底层信道是完全可靠的(虽然这不可能发生),上图中的两个圆圈代表着两个有限状态机(FSM),值得注意的是发送端和接收端都有各自的FSM,并且FSM都只有一种状态。箭头指示着协议从一个状态变为另一个状态(由于rdt1.0中每个FSM都只有一个状态,所以只能指向自己);右侧横线上方的是引起变迁的事件,下方的是应对事件发生所采取的措施;左上角的虚线箭头表示FSM的初始状态。

2.经具有比特差错信道的可靠数据传输:rdt2.0

想象一下当你通过电话口述一条长信息时,如果对方确认收到了,可能会说“OK”(肯定确认);否则会说“请重复一遍”(否定确认),同理,在计算机系统中基于这样的重传机制的可靠数据传输协议被称为自动重传请求协议(ARQ)。

ARQ协议基于另外三种协议来处理比特差错的问题:

  • 差错检测:接收方需要知道何时出现了比特差错。
  • 接收方反馈:接收方需要向发送方提供明确的反馈信息。
  • 重传:接收方接收到有差错的分组时,发送方需重新发送该分组。

与rdt1.0不同的是,每次发送端发送一个分组后,需要等待接收方的反馈(肯定确认ACK或响应重传NAK),在等待反馈的状态下,发送端无法从上层接收新的数据,直到接收端确认接收,这样的协议称为停等协议

看起来rdt2.0已经很完备了,但是却忽略了ACK和NAK分组受损的可能性!这使得发送方无法正确得知接收方是否收到了正确的分组。

两种可能的处理方法:

  • 增加足够多的检验和比特,是发送方不但可以检验差错,还能恢复差错。
  • 当发送方收到受损的ACK或NAK时,重传当前分组即可,但是这产生了冗余分组,使得接收端不知道这是新的分组还是重传。

最终处理方式:

在数据分组中添加一个新字段,让发送方对数据分组编号,也就是说在每个分组前面添加上序号。这样接收方就知道当前数据是新数据还是重传的数据了,这也就是rdt2.0的修订版rdt2.1。

如果不发送NAK,而是对上次正确接收的分组发送一个ACK,我们也能实现同样的效果。发送方接收到对一个分组的两个ACK(冗余ACK)后,就知道接收方没有正确接收到跟在确认两次的分组后面的分组。

rdt 2.2 是在有比特差错信道上实现的一个无NAK的可靠数据传输协议。rdt 2.1和rdt 2.2的区别在于,接收方此时必须包括由一个ACK报文所确认的分组序号。

3.具有比特差错的丢包信道的可靠数据传输:rdt3.0

如果数据在传输的过程中丢失,发送方迟迟收不到接收方的ACK信号,那么发送端应该怎么办呢?显然要确定一个时间值,如果这个时间过后还没有收到回应,则发送端重传一次当前分组。

总之,在 rdt 3.0 中,丢包的问题让发送方解决。不管是发送的分组丢失,还是接收方返回的确认分组丢失,只要在经过一定的时延后,让发送方重发该分组即可。

由此产生的冗余数据分组则由接收方通过序号处理。为了实现基于时间的重传机制,需要一个倒计时定时器。

因为分组序号在 0 和 1 之间交替,因此 rdt 3.0 有时被称为比特交替协议


 3.4.2  流水线可靠数据传输协议

rdt3.0虽然功能正确,但是最大的缺陷在于它是一个停等协议,意味着大量时间花费在等待确认上,使得信道的利用率非常低。

这也就让流水线传输的理念诞生了:数据传输不以停等方式运行,而是允许发送端一次性发送多个分组而无需等待确认。为实现流水线协议,我们需要做到如下几点:

  • 增加序号范围:rdt3.0中只用了0和1来表示当前分组和下一分组,但如果采用流水线以后,会同时存在多个未确认分组报文,而每个分组报文需要有唯一的序号。
  • 发送端和接收端能够缓存多个分组:最低限度下,发送端要能缓存已经发出但未收到确认的分组,接收端要缓存确认接收的分组。
  • 解决流水线差错恢复:为了处理丢失,损坏和时延过大的分组,采取回退N步(GBN)选择重传(SR)两种方法。

3.4.3  回退N步

在回退N步协议中,发送方允许发送多个分组,但是未确认的分组数不能超过最大允许数N。

基序号base为最早的已发出尚未确认分组的序号,下一个序号nextseqnum为即将要发出的分组序号,窗口长度N包括已经发出未确认分组的序号以及马上要被发送出去的分组的序号,随着协议的运行,窗口不断向右滑动,因此GBN协议也被称为滑动窗口协议

发送方需要响应的事件有:上层调用、收到ACK、超时事件。

  • 上层调用:检查next Sequence是否在窗口之内,如果在,这说明发送方还有发送能力,发送之;
  • 收到ACK:回退N步策略对序号为n的分组采取累积确认的方式,即当收到序号为n的ACK时,表明序号小于等于n的分组全部到位,此时窗口向后移动,发送方收到的ACK毕竟来自接收方,收到ACK的情况还得看接收方如何发送;
  • 超时事件:如果发生超时事件,那么发送方会重发所有已发送但是未确认的分组,即分组号在base和next sequence-1之间的所有分组;这也是为什么叫“回退N步”,如果收到一个ACK,则定时器会重行启动;如果没有待确认的分组,定时器将被终止;

接收方需要做的是:当收到序号为n的分组,发送一个ACK给发送端,发送端窗口后移;遇到其他情况(丢包,失序等)时,丢弃该分组,并将最后确认收到的分组的序号k发送ACK,发送端收到ACK后就会知道k号分组后面的数据传输出现问题,随后做出重传操作。

另外,如果分组不是按序到达,那么接收方丢弃所有失序分组,因为丢弃一个正确接收的失序分组可能会导致更多的重传。


 3.4.4  选择重传

回退N步的问题在于单个分组的差错会导致大量分组的重传,随着信道差错率增加,窗口可能会被这些不必要重传的分组所充斥,反而导致传输效率低下。

选择重传(SR)协议通过让发送方仅重传它怀疑出问题的分组,从而避免了不必要的重传。

SR会在分组被正确接收但是失序的情况下向发送端确认接收,然后将其放在缓存中,直到比它序号小的分组全部被接收到以后,才将其拿出,按顺序排列好以后交给上层。 简而言之,SR不管接收到的顺序是否正确,只在意收到的内容是否正确。

SR 发送方的事件和动作:

  • 从上层接收数据: 检查下一个可用于该分组的序号,若在发送方的窗口内,则将数据打包发送。
  • 超时: 定时器再次用来防止丢失分组。但是现在每个分组必须得有单独的定时器。
  • 收到 ACK:倘若该分组序号在窗口内,则 SR 发送方将那个被确认的分组标记为已接收。如果该分组的序号等于send_base,则窗口基序号向前移动到具有最小序号的未确认分组处。如果窗口移动了并且该序号落在窗口内的未发送分组,则发送这些分组。

SR 接收方的事件和动作:

  • 序号在 [rcv_base, rcv_base + N -1] 内的分组被正确接收:在此情况下,收到的分组落在接收方的窗口内,一个选择 ACK 被回送给发送方。如果该分组以前没收到过,则缓存该分组。如果该分组的序号等于接收窗口的基序号,则该分组及以前缓存的序号连续的分组交付给上层。
  • 序号在 [rcv_base - N, rcv_base - 1] 内的分组被正确接收: 产生一个 ACK,即使该分组是接收方以前已确认过的分组。因为视图不一致。
  • 其他情况:忽略该分组。

 窗口会限制发送端的发送,如果2号没有被接收,那么窗口无法向后移动。


3.5  面向连接的运输:TCP

TCP是因特网运输层面向连接的可靠的运输协议。

3.5.1  TCP连接

TCP协议之所以被称为是面向连接的协议,是因为在一个应用进程可以向另一个应用进程发送数据前,这两个进程必须先相互“握手”,即它们必须交换一些预报文段,以建立对关于数据传输的参数的共识。作为TCP连接建立的一部分,通信双方都将初始化与TCP连接的许多相关变量。

TCP连接并不是一条像电路交换网络中的端到端TDM或FDM电路,而是一条“逻辑连接”,也就是说,TCP协议仅仅在端系统中运行,与中间的链路层无关,所以中间的网络元素并不会维护TCP的连接状态,事实上,中间的网络元素对TCP连接完全视而不见,它们只能看到数据报。

TCP服务的特征:

  • 全双工服务:可同时保证双向数据传输。
  • 点对点服务:不可能从一个发送方传数据到多个接收方。
  • 三次握手:客户首先发送一个特殊的TCP报文段,服务器用另一个特殊的报文段响应,最后客户再用第三个报文段响应。其中仅仅只有第三个报文段是有效载荷,能传输数据。

TCP传输数据的流程(以客户进程向服务器发送数据为例):

  1. 客户进程通过套接字传递数据流,TCP将这些数据引导到发送缓存中,发送缓存是三次握手期间建立的,接下来TCP就会时不时从发送缓存中取出数据,进行下一步操作。
  2. TCP每次可以从缓存中取出来的数据数量受限于最大报文段长度(MSS),MSS由最大传输单元(MTU)来设置。一般来说,MSS+TCP/IP首部的长度要小于等于链路的MTU。
  3. TCP会为 每块客户数据 配上一个TCP首部,从而形成多个TCP报文段,然后下放到网络层,网络层将其封装在IP数据报中,发送出去。
  4. TCP接收端接收TCP报文,放置在接收缓存中,然后通过套接字读取数据。 

注意

  • MSS是指再报文段里应用层数据的最大长度,而不是包含TCP首部的报文段长度。
  • TCP的发送端和接收端都有缓存区。

3.5.2  TCP报文段结构

TCP报文段由首部字段和一个数据字段组成,首部一般为20个字节,以32比特为单位组织的;数据字段受到MSS限制,最大长度一般是1460字节。

 TCP首部包含字段:

  • 源端口号目的端口号:用于多路复用/分解来自或送到上层应用的数据。
  • 序号字段:该序号被用于实现可靠数据传输的按序到达,在一个TCP连接中,算是一个报文段的id,同时该id还指示了其所承载的数据的位置信息;占32位。
  • 确认号字段: 该数据表示接收方已经正确接收的报文段的序号,在流水线的差错恢复方案里,不同的恢复策略有不同的意义:回退N步里,当发送方接收到对K的确认号时,表示所有序号小于K的报文段均已到达;而在选择重传里,则仅表示序号为K的报文段被正确接收。
  • 首部长度:  TCP的首部是可变长的,所以该字段表示报文段的首部长度,也揭示了应用数据的开始位置;该字段以32比特为单位,占4比特。
  • 标志字段

    ACK位表示确认号字段的里的值是否有效,如果ACK被置位,那么该报文段就对确认号所指示的报文段进行了确认;RST、SYN和FIN位用于TCP的连接和拆除;PSH被置位时,指示接收方应该立即将数据交给上层;URG被置位时表示报文段里存在着发送端的上层实体置为紧急的数据,紧急数据的最后一个字节由16位紧急指针指出。当紧急数据存在并且给出了指向紧急数据尾指针时,TCP必须通知接收端的上层实体。(然而,实际上,PSH、URG和紧急数据指针在实践中并没有被使用;标记字段一共6比特)

  • 接收窗口:用于流量控制,表示接收方愿意接收的字节数量。

  • 检验和字段:用于差错检查。
  • 选项字段:该字段用于在发送方和接收方之间协商MSS的大小,在高速网络环境下,也可用于调节窗口大小。

注意:

  1. TCP提供累积确认,因为TCP只提供该流中第一个丢失字节处的序号。
  2. TCP将数据看作是一个无结构、有序的字节流,值得注意的是,TCP的序号是基于传输的字节流之上,而不是报文段的序列之上;也就是说,每个字节都有一个编号,如果MSS为1000,来自应用层的数据被TCP包装在多个报文段中,那么第2个报文段的序列号不是2,而是1001。
  3. 确认号是主机期望收到的下一个字节的编号,也就是说如果第一个报文段序号是92,包含8个字节数据,那么第二个报文段的序号就是92+8 = 100号。主机收到第一个报文段后就会返回确认号100.

3.5.3  往返时间的估计与超时

TCP采用超时/重传机制来解决报文段的丢失问题。

1.估计往返时间

在任意时刻,为一个已发送但尚未得到确认的报文段估计样本往返时间(SampleRTT),并结合已经计算出的SampleRTT计算一个SampleRTT平均值。

注意:

  • TCP并不为已经重发的报文段做Sample RTT测试,它只为传输一次的报文段测量Sample RTT。
  • RTT表示某报文段从被交付网络层 到 收到确认的时间量。

TCP一般来说通过Estimated RTT=(1-a)Estimated RTT+a*Sample RTT来计算维持一个SampleRTT的均值(EstimatedRTT)。公式意为过去的均值和新得到的SampleRTT取加权平均值。a一般取1/8,因为Estimated RTT表示最近的网络状况,所以其理应得到较大的权值,这种方法也被称为指数加权移动平均

除了估计RTT外,计算RTT的变化也是有价值的,DevRTT =(1-b)DevRTT+b*|Sample RTT-Estimated RTT|,其中b的推荐值为0.25。当Sample RTT变化较大的时候,DevRTT的值较大,当Sample RTT变化较小的时候,DevRTT就较小。

2.设置和管理重传超时间隔

TCP是如何考虑超时时间的呢?该时间应该略大于EstimatedRTT,但又不宜过小——容易引起不必要的重传,也不易过大——网络对于报文段丢失情况的反应就会变慢;最后TCP采用了如下计算方式:Timeout Interval=Estimated RTT+4*Dev RTT

当出现超时后,TimeOutInteval值将加倍,以免即将确认的后继报文出现过早超时。同时只要出现超时,都应该重新计算TimeOutInterval。


3.5.4  可靠数据传输

IP协议提供的是尽力而为的服务:不保证不丢失、不保证按序到达、不保证没有损坏,TCP协议在IP协议之上,提供可靠数据传输服务,从而保证一个进程从其相关联的缓存中读取的数据和另一端进程发送的数据是一致的。

TCP使用超时重传冗余确认技术来处理超时、丢失等情况;使用确认序号等技术来保证按序到达;使用校验和来检验是否报文段在传输过程中是否发生了错误。

TCP发送方面对的主要事件:

  • 从上层应用程序接收数据:启动定时器->上传数据到IP
  • 定时器超时:重传->启动定时器
  • 收到ACK:判断是否前面还有为确认的报文,有的话就重传

1.超时间隔加倍

在大多数TCP实现中,当发生超时事件时,超时时间并不是从Estimated RTT和Dev RTT推算出来而是直接将超时时间设置为原来的两倍。

然而,每当定时器在另两个事件(收到ACK和接收到上层应用数据)中启动时,新的超时时间将由上面提到的两个值计算出来;实际上,这是一种形式受限的拥塞控制。

2.快速重传

冗余ACK:再次确认某个报文段的ACK,而发送方此前已经收到过该报文的确认。

当接收方收到一个乱序的报文段(例如期望收到2号报文,但是发来的是第3号报文),接收方只需要对已确认的1号报文段进行重复确认一次,如果发送方收到冗余ACK,说明有多个报文段到达了接收端,但不是接收端所期望的——这意味着,很有可能发生了丢失(即上例中的2号报文丢失),所以发送方可以在定时器过时之前快速重传所丢失的报文段。

因为发送方经常一个接一个的发送报文段,如果一个报文段丢失,很可能出现连续的多个冗余ACK,所以我们设定当发送方收到3个相同的冗余ACK,那么就可以确认该报文段确实已经丢失,发送方立刻启动快速重传。

3.是回退N步还是选择重传

首先,我们需要明白的是,TCP采用了累计确认的机制,也就说,如果接收方正确接收了某一失序到达的分组,那么接收方发送的ACK将是对最后接收的按序到达的分组的确认,而不是对刚刚接收的分组的确认。当然,许多TCP实现都会缓存失序的分组,那么问题来了,发生超时事件后,GBN将重传所有待确认的分组,而不是丢失的分组;而选择重传只会重传失序的分组。

对TCP提出的一种修改意见是所谓的选择确认——即接收方对失序到达的分组也会确认,当该机制和重传机制相结合使得TCP更像选择重传,于是TCP的差错恢复协议最好被分类为GBN和SR协议的混合体。


3.5.5  流量控制

流量控制是一个速度匹配服务:TCP连接的发送方和接收方都各自维护一个缓存,因此发送方的发送速率和接收方的接收速率要匹配,不让接收端发生数据溢出。TCP为它的应用程序提供了这种服务:流量控制服务。虽然流量控制和拥塞控制所采取的动作非常相似,但是它们的目的很明显并不同。

TCP通过让发送方维护一个称为接收窗口的变量来提供流量控制,接收窗口用于给发送方一个提示——接收方还有多少缓存空间。那么发送方是如何知道接收方的情况的呢?发送方通过判断已发送但未收到确认的数据量来确认接收方缓存,换句话说,发送方知道接收方会将未及时确认的数据放在缓存中,而已确认的数据会从缓存中拿走,所以发送方只需要知道有多少数据没被确认,即可知道接收方缓存已经占用了多少。

最后一个问题,如果发送方判定接收方已经没有内存了,就会停止发送,但是发送方并不知道接收方什么时候能够处理完缓存中的内容,或者说,当接收端的缓存满了以后,发送方就会无限期停止发送,为了解决这个问题,当发送端判定接收端缓存已满的情况下,发送端会不断向接收端发送1个字节数据的报文,接收端在清理缓存的过程中,会不断回应这些报文,回应报文中会包含一个非0的可用空间值。

还要强调的一点是,UDP并不提供流量控制,因此报文段可能由于在接收方溢出而丢失。


3.5.6  TCP连接管理

TCP连接的建立会显著地增加人们感受到的时延,因此TCP的快速连接显得尤为重要。

一、开始阶段的三次握手

注意:连接过程中主动发起连接邀请的被称为客户端,收到连接邀请的被称为服务器

1.第一次握手

客户端的TCP向服务器端的TCP发送一个特殊的TCP报文段,该报文段不包括应用层数据,但是该报文段的首部的标志位SYN被置为1,因此第一次握手发送的报文段也被称为SYN报文段。此外,客户端会随机选择一个初始序号(client_isn),一并放在SYN报文段的序号字段中。SYN报文段随后被封装在IP中发送给服务器。

状态变化:客户端初始时为CLOSED状态,发送完成后进入SYN_SENT状态。

总结:SYN=1的报文段不含有数据,但是含有一个随机序号。

2.第二次握手

服务器收到客户端的SYN请求报文后,会为TCP连接分配缓存和变量,随后向客户端TCP发送允许连接的报文段SYNACK报文段。

SYNACK报文段同样不包含应用层数据,但是包含三个重要信息:

  • SYN比特被置为1:表示服务器确认收到了客户端发起连接请求的SYN分组。
  • 确认号字段被置为client_isn+1:表示服务器确认收到了SYN报文段的初始序号client_isn,希望客户端发送序号client_isn+1开始的字节。
  • 服务器自己的初始序号server_isn:表示服务器同意建立连接,且自己作为发送端发送的序号会从server_isn开始。

状态变化:服务器从LISTEN状态进入SYN_RCVD状态。

3.第三次握手

客户端收到SYNACK报文后,为连接分配缓存和变量,并且发送最后一个确认报文,其中包含SYN=0(表示连接建立完毕),确认号字段server_isn+1(确认收到服务器初始序号)。

状态变化:客户端发送完后进入ESTABLISHED状态,服务器收到报文后进入ESTSBLISHED状态。

注意:第三次握手的报文中可以携带数据。

二、结束阶段的四次挥手

参与TCP连接的双方都可以提出终止连接,接下来假设客户端主动提出终止连接。前两次挥手用于断开客户端到服务器的连接,后两次挥手用于断开服务器到客户端的连接。

1.第一次挥手

客户向服务器发送首部标志位FIN=1的报文,表示请求断开连接。客户端从ESTABLISHED状态进入FIN_WAIT1状态,服务器还是ESTABLISHED状态。

2.第二次挥手

服务器确认收到请求(ACK=1)。服务器进入CLOSED_WAIT状态,客户端收到报文后进入FIN_WAIT2状态。

注意:第二次挥手结束后,客户端不能向服务器发送数据,但是服务器可以向客户端发送。

3.第三次挥手

服务器发送首部标志位FIN=1的报文,请求终止另一方向的连接。服务器进入LAST_ACK状态。

4.第四次挥手

客户端确认收到报文(ACK=1),正式断开连接。客户端进入TIME_WAIT状态,服务器收到ACK后,双方进入CLOSED状态。


3.6  拥塞控制原理

拥塞控制机制就是在面临网络拥塞时遏制发送方的手段。

 3.6.1  拥塞原因与代价

1.情况一:两个发送方和一台具有无穷大缓存的路由器。

 结论: 当分组的到达速率接近链路容量时,分组将经历巨大的排队时延。

2.情况二:两个发送方和一个具有有限缓存的路由器。

 结论:发送方必须执行重传已补偿因为缓存溢出而丢弃的分组;发送方遇到大时延时所进行的不必要重传会引起路由器利用其链路带宽来转发不必要的分组副本。

3.情况三:4个发送方和具有有限缓存的多台路由器和多条路径。

 结论:当一个分组沿着一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费掉了。


3.6.2  拥塞控制方法

根据网络层是否提供显式帮助粗略的分为两种控制方法。

1.端到端拥塞控制 

在这种方法中,网络层没有对运输层的拥塞控制提供显式支持,即使存在拥塞,端系统也必须通过对网络层行为的观察来推断。TCP必须通过端到端的方法解决拥塞控制,因为IP层不会像端系统提供有关网络拥塞的反馈信息。TCP报文段的丢失(超时或者收到3次冗余确认而得知)被认为是网络拥塞的一个迹象,遇到拥塞时,TCP将相应地减小窗口长度。

2.网络辅助的拥塞控制

网络层会向发送方提供关于网络中拥塞状态的显式反馈消息,比如使用一个比特位来指示网络是否拥塞。拥塞信息从网络反馈到发送方一般有两种方式,其中直接反馈信息可以由网络路由器发送给发送方,这种方式的通知通常采用一种拥塞分组的形式;第二种形式的通知是路由器标记或者更新从发送方到接收方的分组中的某个字段来指示拥塞的产生,然后由接收方向发送方通知该网络发生了拥塞。


3.7  TCP拥塞原理

3.7.1  经典的TCP拥塞控制

我们已经知道,TCP使用端到端的拥塞控制,让每一个发送方根据其所感知的网络拥塞程度来限制其能向连接发送流量的速率:如果TCP判断网络通畅,那么它会提高发送速率;如果TCP判断网络拥塞,那么它会限制发送速率,那么现在就有三个问题:TCP如何限制发送速率?TCP如何感知网络拥塞程度?当感知到拥塞时,TCP该以何种算法改变其发送速率?

1.TCP如何限制发送速率?

TCP的双方都会维护两个窗口,一个是接收窗口(rwnd),另一个是拥塞窗口(cwnd),拥塞窗口会对TCP发送方向网络中发送流量的速率进行了限制:在一个发送方中未被确认的数据量不会超过cwnd与rwnd中的最小值

我们假设,发送方可以在RTT时间范围内连续发送cwnd个字节的数据,所以发送速率大概为cwnd/RTT 字节/秒,发送方可以通过调整窗口大小来对发送数据的速率加以控制。

2.TCP如何感知网络拥塞程度?

我们将TCP发送方的丢包事件定义为:要么超时,要么收到接收方的3个冗余ACK。如果网路拥塞,那么网络中的路由器就会发生缓存溢出,进而导致数据报被丢弃,然后就会引起发送方的丢包事件,此时,TCP发送方就可以认为TCP连接出现了拥塞。

另外,TCP将接收方发送的ACK视为网络通畅的标志,如果ACK到达的速率较高,那么TCP的拥塞窗口就会以较高的速率扩大;如果ACK到达的速率较慢,那么TCP拥塞窗口的增加速度也会较慢,因为TCP使用ACK对拥塞窗口做出调节,所以也别称为自计时的。

3.TCP以何种算法确认合适的发送速率?

TCP发送速率过高,网络就很容易拥塞;TCP发送方如果过于谨慎,那么就无法充分利用网络的带宽。所以TCP如何设置自己的发送速率,才能使得网络不会拥塞而且还充分利用带宽呢?关于这个问题,TCP使用下列指导性原则回答这些问题:

  • 一个丢失的报文段意味着拥塞,因此当丢失报文段时应当降低TCP发送方的速率。
  • 一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当收到对先前未确认报文段的确认时,可以增加发送方的速率。
  • 带宽检测。TCP调节器传输速率的策略是增加其速率以响应到达的ACK,除非出现丢包,此时才减少发送速率,简单来说,发送端在开始时会不断提高发送速度,并检测拥塞速率是否发生变化,直到发现有拥塞情况发生以后,才稍微放慢速度。

概述了TCP拥塞控制后,下面我们将考虑TCP拥塞控制算法的细节,该算法主要包括下面三部分。

1.慢启动

在启动阶段,cwnd(拥塞窗口)的值以一个MSS(最大长度的报文段)开始,当收到确认ACK后,TCP将拥塞窗口增加一个MSS,并发送两个MSS长度的报文,当这段报文被接收后,拥塞窗口的长度再增加两个MSS,并发送四个MSS长度的报文,以此类推,TCP发送速率开始慢,然后越来越快,以指数级别增长(1,2,4,8······)。

何时结束这种指数增长呢?有三种情况:发生了超时、发生了冗余ACK以及cwnd达到ssthresh。ssthresh是慢启动阈值的速记,在慢启动阶段,如果发生了超时事件,那么ssthresh就被设置为当前cwnd的一半(即前一个指数长度),然后将cwnd置为1,当cwnd再一次逐步增加到ssthresh时,再翻倍增加cwnd就有一点鲁莽了,所以此时TCP结束慢启动,进入拥塞避免模式。在拥塞避免模式里,TCP将更谨慎地增加cwnd,如果收到冗余ACK,那么TCP会做一次快速重传,然后进入快速恢复阶段。

2.拥塞避免

当我们上面所说的cwnd再一次逐步增加到ssthresh时,也就是cwnd差不多为上一次发生拥塞时的值的一半,启动拥塞避免。此时每收到一个ACK时,只将cwnd的长度增加一个MSS,而不是翻倍,也就是说,在拥塞避免模式中,cwnd的长度线性增加。

当出现超时时,TCP将cwnd设置为1,然后将ssthresh更新为cwnd的一半;当收到冗余ACK时,TCP将cwnd减半,然后将ssthresh置为cwnd值的一半,并且进入快速恢复状态

3.快速恢复

在快速恢复阶段,对于引起TCP进入该状态的缺失报文段,每收到一个ACK,cwnd增加一个MSS,最终,当对丢失报文段的一个ACK到达时,TCP降低cwnd后进入拥塞避免状态;如果出现超时事件,快速恢复在执行如同慢启动和拥塞避免中相同动作后,进入慢启动状态。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值