计算机网络TCP的可靠传输 流量控制 拥塞控制 详解

Posted 呋喃吖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机网络TCP的可靠传输 流量控制 拥塞控制 详解相关的知识,希望对你有一定的参考价值。

TCP可靠传输–停止等待ARQ协议

为了保证TCP的可靠传输,也就是保证这个数据包一定会传输到给对方,早期的处理手段是使用了一种体制等待ARQ的方法去解决这个问题;在早期,发送数据包给对方时候,是发送一个包,等对方确认后才可以继续发送下一个包。

为了保证可靠传输,要考虑多种情况;
第一种情况,就是无差错的情况:A发送过去,B再发一个确认包回来;如此反复知道A发完;


第二种情况,就是超时重传:A发送过去,B没有接收到,或者B接收到,没有回复确认包给A,此时,超过一定时间,A就会重传这个B没有收到的数据包;这也是为了保证可靠传输;


第三种情况,确认丢失:当A给B发送数据包时候,B收到了数据包,但是B再发一个确认包给A时候,丢失了,或者超时了,此时A就会超时重新发送数据包给B,当B收到A在次发送的数据包时候,丢弃掉A原来发过的一模一样的数据包,B确认重传一个确认包给A;


第四种情况:就是确认迟到:当A给B发送数据包时候,B收到了,但是由于B的回复确认数据包给A时候迟到了,那么即使,A收到了确认包,但是什么也不会做,意思是,不会再发送下一个包给B了,因为它迟到了,并且在它迟到前,已经完成了发送下一个包给B了,所以确认迟到的包是不会做任何事情;


上面的停止等待协议确实可以做到保证TCP的可靠传输,可是这种机制效率过于低下,因为每发一个数据包过去,都需要对方一个确认包才可以继续发送下一个包,所以说这种效率比较低下,我们现代使用的另一种连续停止等待ARQ协议+滑动窗口的机制,完美解决了可靠传输问题+效率的问题,接下来我会分享这种机制的思想原理。


TCP可靠传输–连续ARQ+滑动窗口协议


如上图的右边的图要A计算机要发送M1到M12的数据过去给给计算机B,不是一个一个发,而是一段一段发的,比如一次发4个,而计算机B只需要给一个确认即可A即可,不需要给4个确认,并且确认只需要确认一次发的最后一个数据包的编号即可,比如上面的A计算机一次发M1-M4,那么也就是说B回应只需要回应确认M4即可,这表明B是收到前面4个数据包,发完后继续滑动到M4-M8的窗口位置继续发送。
一般来说,滑动窗口的大小都是在TCP建立连接的过程中就知道的。


举个例子:假如有1200字节的TCP数据部分,分成12份要发送出去;

  1. A为发送方,B为接收方;
  2. 首先在发送数据前,要建立连接,建立连接过程中,B就告诉了A,B的发送窗口大小为400,那么A就会设置自己窗口大小也为400;也就是说A发送数据给B,是一次发400个字节过去的;
  3. 在B中,B收到400个数据后,不是马上交给应用层处理,而是先放到自己的接收缓存中保存,并且把记得的滑动窗口移动到下一个空位,一边接收A再次发过来的数据;
  4. 当B接收到A的400个字节后,B就会给一个确认号给A,期望它从401个字节发送过来;
  5. 此时A收到B的确认数据包后,就会设置自己的滑动窗口往前移动,并且在确认对方B收到了前面400个字节后,会把自己接收缓存的已经发送过去的400个字节清除掉,继续重复上诉步骤发送接下来的数据包。

我们可以注意观察细节,发送数据包过去时候,我们每个包的序号为1,101,201,301,即表示这一次发送过去给B的TCP包数据部分的第一个字节为1,101,201,301;
并且我们观察B发回来的数据包,是ACK标志位为1,表面确认号是有用的,而此时确认号为401,表示B计算机希望A计算机下一次发送过来的数据是从401个字节发送过来!



  1. 那么接下来我们在A发送5-8个包过去,此时假如发现第7个包丢失了;
  2. 那么计算机B中的滑动窗口就不会直接滑到第9个包开始了,而是滑动到丢失的第7个包开始;
  3. 并且计算机B回复确认包给A时候,也不会发送确认号为801,而是从601的确认号,如果发送801确认号,那么就表明前面的4个包B都收到,期待A从901开始发送,但实际上却不是,因为丢失了一个601的包,所以确认好只能从601开始;
    那么表面希望A从601开始发送,但是我们知道从601开始发送,一次发4个,一定会包含之前发送过的701数据包,那么也就是说,假如直接从601开始发送,那么701数据包就会重复发送,显然这是浪费资源的,没必要重发一个发过的包;
    所以TCP保证发过的的包不重复发送,引入了一个机制为SACK机制,也叫选择性确认机制



如果有个包重传N次还是失败那么会一直重传到成功吗?

不会,一般都是重传几次,还是失败后就不会重传了,这一般都取决于操作系统的设定!
比如有些操作系统重传5次还没有收到确认包后,那么就不会再重传这个包了!

一般重传N次还是没有收到确认,那么就会发送一个报文首部字段中RST为1,表示这个包传输失败,即会断开TCP连接!


TCP数据包为什么在传输层切片,不在网络层和数据链路层切片?

因为传输层可以保证可靠传输,在传输层把TCP大包切片,假如接受方收到的发送方的包不是完整的话,也就是说发送方发送的包有丢失的,那么就可以在传输层重新传输丢失的包,而不用重新传输整一个大包过去
假如在网络层或者数据链路层切片,那么一旦接受方收到的TCP是不完整的,那么只能让传输层重新传送一个大的TCP包过去,很明显丢的是少数的包,却要传送一个大包过去,效率及其低下有人会问,为什么不在网络层或者数据链路层传送过去丢失的包呢?因为网络层和数据链路层不保证可靠传输,没有这个机制,也就无法确定是哪个包丢失了,只能从传输层重新传!



接收窗口大小比发送的数据还要大,TCP会一直等数据填满接收窗口吗?

不会,因为TCP也是有一定的机制控制这个问题:
假如接收窗口时接收4个包,发送却发了2个,接受方不会一直傻等,超过一定时间后发现没有后序的包过来,那么就会发送一个确认包给发送方,确认收到了前面两个包。


TCP流量控制

TCP的数据包,为什么需要流量控制,流量控制的背景来源于哪?
我们知道,接受方都会有一个接收缓存区,也就是用来接收发送方发送过来的数据包的存储区;
也就是说,假如我们的接收方的缓存区满了话,发送方还在源源不断的发送过来给接受方,那么接收方就会丢弃发送方发过来溢出的缓存区,为了保证数据不被丢弃,我们就需要控制发送方发送数据的数率,让接受方来得及处理。



我们的窗口字段,不是固定不变的,而是动态变化的,会根据网络的拥堵情况,发送数据速率情况而变化,这个窗口字段一般可以控制TCP发送的速率!


TCP流量控制–特殊情况


TCP拥塞控制


如上图:假如通过R3路由器最大宽带为1000M;那么R1和R2加起来的流量理论最大也为1000M;可是实际情况却不是这样,即使最大旷代为1000M,能通过该路由器R3也是不足1000M的,那么也就是说,通过R3会有拥塞情况!
当通过R3的宽带越来越大时候,那么传输的数据包的速率就会增大的速率越来越低,到达一定的阈值后,假如害继续增加传输的宽带的话,那么传输速率就会开始降低。
就类似车道一样,当车辆比较少时候,通过速度很快,当塞车时候,也是车很多时候,那么通过的速度就会变慢;


拥塞控制就是:防止过多的网络包传入到网络中,避免路由过载!


拥塞控制时全局性的过程,需要各个主句路由器一起维护;而我们的流量控制,通常是点对点,传输层对传输层的结果!


TCP拥塞控制–方法

如何对TCP拥塞进行控制呢?我们有四种算法来进行拥塞控制!

先看看几个常见的缩写:


MSS一般是TCP可选字段才会出现,一般在建立连接时候会确定;

并且我们通常见到的TCP头部都是20个字节,一般在前两次建立连接时候我们的TCP头部会是32个字节,比较常见的,多出的12个字节是在可选部分的,一般存放一些其他信息:
比如这里的建立连接的TCP包的可选部分,有一个信息表示数据段的最大值是多少;
接收窗口表示接收方的接收窗口一次最多可以接收多少字节的数据;
拥塞窗口:它会变动的,其实就是根据网络情况变动,网络好时候,拥塞窗口比较大,网络不好拥塞窗口比较小;
发送窗口表示发送方一次可以发送的多少个字节数据的大小;通常发送窗口的值 = min(拥塞窗口,接收窗口)


比如发送方:有6000个字节数据要发送,分6个包,每个包为1000个字节,假如发送方的拥塞窗口为5000,而接收窗口的大小为3000;那么发送方的发送窗口的值就是接收窗口值得大小为3000;
也就是说发送方只能一次最多发3000个给接收方;
假如发送方拥塞窗口为2000,接受方的接收窗口为3000,那么发送窗口的为2000,即使接收方可以接收3000,但是用于网络状况不好,拥塞窗口比较小,那么只能发送2000过去;


总的来说,拥塞窗口是可以根据网络状况而发生变化,用来控制TCP的拥塞情况!


TCP拥塞控制–慢开始算法


TCP如何进行拥塞控制的呢?
我们知道TCP为了保证效率,在建立连接后,不是一个包发送过去,再等对方一个确认再回来,而是多次发送对方接收窗口大小的数据,,然后再给回一个确认包。
但是TCP为了能够拥塞控制,刚开始并不是直接一大堆包发送过去,而是使用一个包2个包4个包8个包。。。慢慢的去试探的,拥塞窗口也会慢慢的增大,也就是所谓的慢开始算法。


如上图,显示,这就是慢开始,那什么时候知道增加到的数据包到一定层度就发现网络拥塞了呢?
很容易,只要发现丢包了,就可以开始发现差不多是到达网络拥塞点了。发送方一直发送包过去,接收方都还没有确认包回来,这时候就可以认为是网络拥塞了。


TCP拥塞控制–拥塞避免算法


我们的TCP里面会设置一个阈值,也就是cwnd的阈值,ssthresh,一旦发现cwnd的值达到了该阈值,那么TCP包发送的速率就不会指数增长,就会开始线性增长,也就是所谓的以第一拥塞避免方式,加法增大算法;
当增大到一定的值,也就是网络状态不好时候,这时候就可能会丢包,然后TCP包发送速率也就会开始降低,也会把拥塞的峰值减半,如上图峰值为2400,减半到1200;也就是所谓的乘法减少,就是乘于0.5倍的减少峰值,再开始慢开始算法。


TCP拥塞控制–快重传算法


如上图,发送方发送了一个M1包,接收方收到并回复确认包给发送方,
当发送方给接收方发送M3时候,丢失了,发送方还是会继续发送下个M4M5M6过去,但是接收方却不会回复确认收到M4M5M6的包过去,只会一直重复确认M2的包,表示希望发送方给我发送M3的包过来,M2的包我收到了,当接收方回复3次确认包M2给发送方时候,此时发送方就会意识到,自己的M3包已经丢失,必须重新传,这就是快重传;
假如没有快重传机制,也就是之前我们在可靠传输的超时重传机制,那么接收方不会继续发送M4M5M6,而是等待接收方发送确认收到M3包过来才会继续,假如没有收到,那么就会等待一定时间再重传,然后重传结束后再继续传接下来的M4M5M6。



TCP拥塞控制–拥塞避免+快重传


当rwnd的值达到了峰值时候,也就是发生快重传时候就能够知道rwnd是达到网络峰值了,这是候就会开始乘法减小,峰值减半,并且ssthresh阈值也开始减小,减小多少都是TCP设计者规定的,然后开始拥塞避免算法,线性增加rwnd的值,此时不会开始慢开始算法了,这种算法被抛弃了,因为效率不够高;

TCP–拥塞控制–快恢复算法

以上是关于计算机网络TCP的可靠传输 流量控制 拥塞控制 详解的主要内容,如果未能解决你的问题,请参考以下文章

计算机网络湖科大微课堂笔记 p60-63 TCP的流量控制拥塞控制超时重传时间的选择可靠传输的实现

TCP可靠传输滑动窗口流量控制拥塞控制

TCP可靠传输滑动窗口流量控制拥塞控制

TCP可靠传输滑动窗口流量控制拥塞控制

TCP可靠传输滑动窗口流量控制拥塞控制

计算机网络:可靠传输的实现 (tcp窗口滑动以及拥塞控制)