【计算机网络】——TCP保证可靠传输详解

文章目录

  • 1、TCP实现可靠性传输概述
  • 2、可靠传输的工作原理之确认应答、超时重传
    • 2.5停止等待协议
    • 2.6连续ARQ协议
  • 3、可靠传输的工作原理之滑动窗口流量控制
    • 2.1零窗口问题
    • 2.2糊涂窗口综合症
    • 2.3Nagle算法
  • 3、TCP可靠传输之拥塞控制
    • 3.1拥塞控制的基本概念
    • 3.2拥塞控制的几种方法

1、TCP实现可靠性传输概述

我们一直在讲TCP是有连接,可靠的,面向字节流的传输协议,那么TCP是如何实现其可靠性呢?主要从下列三个方面来保证TCP可靠性:

  1. 保证数据能够到达对方:通过应答确认、超时重传保证数据的无差错到达滑动窗口保证发送方发送数据和接收方速率匹配拥塞控制保证发送发发送数据的速率与当前网络情况相匹配来保证。
  2. 保证数据不重复、不乱序:通过32位seq序列号保证,因为seq的初始值是随机生成的,在三次握手结束后,保证了通信的双方知道彼此的初始化seq,这个序列号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输问题而乱序。TCP会用这个序号来拼接数据,这样就可以保证数据的不重复,有序。
  3. 保证数据不失真:通过报文首部的16位校验和保证,添加12字节的伪首部进行检验,一般采取CRC冗余检验实现。

2、可靠传输的工作原理之确认应答、超时重传

当我们的网络不具备理想的传输条件时不能采取任何的措施来实现可靠传输,由此我们就要使用一些靠传输协议
当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的数据,即实现TCP传输时的应答确认、超时重传,主要有两种协议:停止等待协议和连续ARQ协议。

2.5停止等待协议

1、概念
从字面意思上我们就可以很好的理解,就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组

在全双工通信的双方既是发送方也是接收方,我们现在假定A发送数据,B接收数据,因此A叫做发送方,B叫做接收方,传送给的数据单元都成为分组。

在使用停止等待协议时,A,B端会有以下几种情况出现:无差错情况,出现差错,确认丢失,确认迟到。下面我们来一一讲述。

2、不同情况下的停止等待协议
2.1无差错的情况
从下图中,我们可以看到A发送一个分组过后要等待B回复确认过后才能发送下一个分组。
【计算机网络】——TCP保证可靠传输详解_第1张图片
2.2出现差错的情况
出现差错的情况一般有两种:

  • B接收M1时检测出了差错
  • M1在传输的过程中丢失了

这时B就会自动丢弃有差错的分组,并不会去通知A,A只要超过一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,就重传前面发送的分组,这也就是我们之前所说的超时重传机制,如下图所示:
【计算机网络】——TCP保证可靠传输详解_第2张图片
【补充】超时重传机制

  • 在每发送的一个分组设置一个超时计时器,这个时间的设置采用TCP提供的自适应算法得到,如果在超时计时器到期之前收到了对方的确认,就撤销已设置的超时计时器
  • 否则就进行重传

【注意】

  1. 必须暂时保留已发送的分组副本,只有在收到相应的确认后才能清除暂时保留的分组副本
  2. 分组和确认分组都必须进行编号
  3. 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。太长通信效率会降低,太短会产生不必要的重传。

2.3确认丢失
当B所发送的对M1确认丢失了导致A在设定的超时重传时间内没有收到确认。A会在超时计时器到期后重传M2。这时B又收到了重传的分组M2,这时会采取两个行动:

  • 首先,丢弃这个重复的分组M2,不向上层交付
  • 接着,向A发送确认。

具体的如下图所示:

【计算机网络】——TCP保证可靠传输详解_第3张图片
2.4确认迟到
当传输过程没有出现差错,但B对分组M1的确认迟到了,A会收到重复的确认,对重复确认的处理就是收下后丢弃。B仍然会收到重复的M1,并同样要丢弃重复的M1,并重传确认分组,如下图所示:
【计算机网络】——TCP保证可靠传输详解_第4张图片
3、总结

  • 通常A最终总是可以收到对所有发出的分组的确认,如果A不断重传分组但总是收不到确认,就 说明通信线路太差,不能进行通信
  • 使用上述的 应答确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信

2.6连续ARQ协议

1、概念
接收方一般都是采用累积确认的方式,对按序到达的最后一个分组发送确认。
关键点就在于如下图的窗口内5个分组都可以连续发送出去,而不需要等待对方的确认。
【计算机网络】——TCP保证可靠传输详解_第5张图片
发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。 如下图表示发送方收到了对第一个分组的确认,于是就把发送窗口向前移动一个分组的位置,如果原来已经发送了前5个分组,那么现在就可以发送窗口内的第6个分组了。
【计算机网络】——TCP保证可靠传输详解_第6张图片

2、特点

  • 优点就是容易实现,即使丢失也不必重传
  • 缺点就是不能向发送方反映出接收方已经正确收到所有分组信息

【举个栗子】如果发送方发送了前5个分组,而中间的第3个分组丢失了,这时接受方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次,这就叫做Go-back-N(回退N),表示需要再退回来重传已发送地N个分组。可见当通信线路质量不好时,连续ARQ协议会带来负面的影响。

3、可靠传输的工作原理之滑动窗口流量控制


1、什么是滑动窗口?
在我们的确认应答机制当中,对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段。
但是仔细想想这种机制的话似乎性能比较差,尤其就是数据往返时间较长的时候。由此,我们就提出了滑动窗口来一次发送多个数据。

2、滑动窗口的作用?
主要是用来流量控制的。所谓流量控制就是让发送方的发送速率不要太快,让接收方来得及接收

【举个栗子】
假如A向B发送数据,在连接建立时,B通过报文段首部告诉A:“我的接收窗口rwnd=400”,因此,发送方即A的发送窗口不能超过接收方给出的接收窗口的数值。这里的TCP窗口单位是字节,不是报文段。设置一个报文段DATA为100字节长,数据报文段seq的初始值设为1,ack表示确认字段的值,那么流量控制如下图:
【计算机网络】——TCP保证可靠传输详解_第7张图片
在整个过程中,接受方的主机B进行了 三次流量控制

  • 第一次把窗口减少到rwnd=300,这时发送端的发送窗口缩小。
  • 第二次又减到rwnd=100。
  • 第三次减少到rwnd=0, 即不允许发送方再发送数据了。我们将这个窗口称为零窗口,这个状态将持续到主机B重新发出一个新的窗口值位置

3、窗口类型

  • 接收端窗口rwnd:接收端缓冲区大小。接收端将此窗口值放在TCP报文的首部中的窗口字段,传送给发送端。
  • 拥塞窗口cwnd:发送端缓冲区大小
  • 发送窗口swnd:发送窗口的上限值= Min [rwnd, cwnd]。

4、运行机制
如下图所示,假设窗口大小是4000.那么就是说图上10001-5001之间的数据是可以一次性全部发送,并且不需要等到ACK响应的。当发送完这4000的数据之后,此时等待。等到ACK响应中确认收到10001-2000的数据时,窗口右移。
【计算机网络】——TCP保证可靠传输详解_第8张图片
【计算机网络】——TCP保证可靠传输详解_第9张图片
从图中可以看到,发送窗口的位置由窗口的前沿和后验位置共同确定。对于已经收到ACK应答的数据显然是不需要保留的。后面未发送的数据没有为这部分保留临时存放的缓存空间。

2.1零窗口问题

1、概念
从字面意思我们可以非常容易的来理解零窗口问题就是发送端在窗口变成0,这样发送端就不会发送数据了。
但是此时当接收端B接收缓存中有了一些存储空间时,B向A发送了rwnd=400的报文段,但是这个报文段在传送过程中丢失了,A一直等待收到B发送的非零窗口通知,而B也一直等待A发送的数据,如果没有其他措施,这种相互等待的死锁局面将一直延续下去,这就是零窗口问题。

2、解决办法
为了解决这个问题,TCP为每一个连接设有 一个持续计时器

  • 只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器
  • 若持续计时器设置的时间到期,就发送一个 零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值
  • 如果窗口仍然是零,那么收到这个报文段的一方就重新设置持续计时器,如果窗口不是零,那么死锁的僵局就可以打破了。

2.2糊涂窗口综合症

1、概念
设想一种情况:TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1个字节,这样就使得接收缓冲区仅腾出1个字节:

  • 接收端向发送方发送确认,并把窗口设置为1个字节,但发送的数据报是40字节长(20IP头+20TCP头)
  • 接着,发送方又发来1个字节的数据,那么数据报长度为41字节,固定头部40,真实数据1字节,接收端发回确认,窗口仍然设置为1个字节。

这样循环进行下去,使网络的效率很低,这就是我们说的糊涂窗口综合征,又称为小窗口问题,总结来说就是每次发送很小的字节,却需要40字节的固定头部,数据报固定开销远远大于数据部分,这样会导致网路效率低

2、弊端和解决方法
仔细想想,这样的处理方式似乎有些许不足。要知道TCP+IP头有40个字节,为了这几个字节,要搭上这么大的开销,显然不是很经济的做法。所以我们提出了以下的方式来解决。

  1. 发送方发送方也不要发送太小的报文段,否则会引起接收端的多次确认,浪费内存,而是把数据报积累成足够大的报文段,或达到接收方缓存的空间的一般大小,这就是Nagle算法
  2. 接收端:可以 让接受方等待一段时间,使得接收缓存已有足够空间容纳一个最长的报文段,或者 等到接收缓存已有一半空闲的空间。只要出现 这两种情况之一,接收方就发出确认报文,并向发送方通知当前窗口大小。

这两种办法可配合使用,使得在发送方不发送很小的报文段的同时,接受方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。

2.3Nagle算法

1、使用场景
该算法是默认打开的,如果需要关闭可以在socket设置TCP_NODELAY选项来关闭。
一般用于需要小包场景的程序——比如像telnet或者ssh这样交互性比较强的程序。解决糊涂窗口综合征

2、算法详情

  • 若发送应用进程把要发送的数据 逐个字节的送到TCP的发送缓存,则 发送方就把第一个数据字节先发出去,把后面到达的数据字节都缓存起来。
  • 当发送方收到第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去, 同时继续对随后达到的数据进行缓存。

Nagle算法还规定, 当到达的数据已达到发送窗口大小的一半或已达到报文段的最大程度时,就立即发送一个报文段。

3、TCP可靠传输之拥塞控制

3.1拥塞控制的基本概念

1、什么是拥塞控制?
简单来说,拥塞控制就是考虑到当前的网络情况,动态调整窗口大小,没有发送拥塞的情况,则窗口增大,拥塞了就窗口减小。如此往复,最终应该接近与接收端窗口大小。

2、窗口类型

  • 接收端窗口rwnd接收缓冲区的大小,接收端将此窗口值放在TCP报文的首部中的窗口字段,传送给发送端。存放按序到达的,但尚未被接收应用程序读取的数据和未按序到达的数据。
  • 拥塞窗口cwnd:大小取决于网络的拥塞程度,并且在动态的变化。
  • 发送窗口swnd:发送窗口的上限值=Min=[rwnd,cwnd],存放已发送未确认的数据和可发送但还没发送的数据

即,当rwndcwnd时,则是网络拥塞限制发送方窗口的最大值。
3、拥塞控制和流量控制的区别?

  • 拥塞控制就是防止过多的数据注入网络中,这样可以使得网络中的路由器或链路不致过载
  • 流量控制指的是根据接收端的处理能力,来决定发送端的发送速度。以便接收段来得及接收

3.2拥塞控制的几种方法

在讨论这几种拥塞控制的方法之前我们假定:数据是单方向传送,而另一方向只传送确认;接收方总是有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定。
下图表示了拥塞动态控制的一个过程

【计算机网络】——TCP保证可靠传输详解_第10张图片
发送方维持一个叫做拥塞窗口cwnd的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态的在变化。发送方可以根据没有按时收到应当到达的确认报文就可以猜想网络可能出现了拥塞。
1、慢启动

从上图我们可以清楚的看到,在慢启动阶段是由小到大逐渐增大发送窗口。
在刚开始发送数据的时候,因为不知道当前的网络环境是怎样的,为了避免大量数据一次性发送而造成的拥塞想想。先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是探测一下网络的拥塞情况),然后再逐渐成指数性增大cwnd。

2、拥塞避免
当达到门限值过后,以线性递增的方式增大拥塞窗口(这里的递增时间间隔为一个往返时间RTT)

【注意】慢启动和拥塞避免在传输开始时配合使用,为了防止拥塞窗口cwnd增长过快引起网络阻塞,还需要设置一个 慢开始门限ssthresh,用法如下:

  • 当cwnd,使用慢开始算法
  • 当cwnd>ssthresh时,停止使用慢开始算法,改用拥塞避免算法。
  • 当cwnd=ssthresh时,即可以使用慢开始算法,也可以使用拥塞避免算法。

3、快速重传

  • 首先要求== 接收方每收到一个失序的报文段后就立即发出重复确认==,为的是 使发送方及早知道有报文段没有到达对方,而不要等待自己发送数据时才进行捎带确认。
  • 发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而 不必等待报文段的重传计时器到期。

【计算机网络】——TCP保证可靠传输详解_第11张图片

4、快速恢复

  • 当发送方连续收到三个重复确认时,就执行乘法减小算法,把慢开始门限ssthresh减半,这是为了预防网络发生阻塞。
  • 由于发送方现在认为网络可能没有发送拥塞,因为如果网路发生严重的拥塞,就不会一连有好几个报文连续到达接收方,更不导致接收方连续发送重复确认,因此现在不执行慢开始算法,即cwnd=1,而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大(每次增加一个)。

【思考?拥塞窗口大小为什么先以指数增加再以线性增加?】
窗口大小首先以指数递增去探测一下网络的拥塞程序,执行拥塞避免算法后,拥塞窗口线性增大,防止网络过早出现拥塞。

5、拥塞控制的作用?
下面这张图就能清楚的说明其作用。
【计算机网络】——TCP保证可靠传输详解_第12张图片
从上图中我们可以明确的看到

  • 如果没有拥塞控制,当网络吞吐量明显小于理想的吞吐量时,网络就进入轻度拥塞的状态
  • 当提供的负载到达某一数值时,网络的吞吐量反而随提供的负载的增大而下降,这时网络就进入了拥塞状态。
  • 当提供的负载继续增大到某一数值时,网络的吞吐量就下降到0,网络已无法工作,这就是所谓的死锁。
    拥塞避免可以很好的解决以上遇到的问题。

你可能感兴趣的:(计算机网络)