TCP传输控制总结

2019-01-19  本文已影响0人  _Seng_

摘要

鉴于TCP传输控制过程比较复杂,单单看书就已经看了3、4遍,为加深理解,本文主要对相关机制作一个通览式的复习总结说明,如TCP是如何对成块式数据流进行流控的,慢启动、拥塞避免的机制是什么;不涉及太深的细节,文中大多内容出自于《TCP/IP协议详解 卷1:协议》。学识有限,如有错漏,请不吝指正。

前置知识

阅读本文需要具备的前置知识:

TCP应用分类

如果从传输的应用数据量级大小来看,TCP应用可以分为两大类:

在实际中要判断一个应用是属于交互式数据流,还是属于成块数据流,还是需要根据具体的实际情况进行判断。

TCP基础特性

TCP经受时延确认(ACK)

TCP在接收到数据时并不立即发送ACK,相反,TCP推迟发送,以便将ACK与需要沿该方向发送的数据一起发送(如果有新数据需要发送,则立即和ACK一起发送,否则等待,最大等待200ms)

重复确认ACK

接收方每当收到1个失序的报文,就重复一次失序前的那个报文的ACK。

交互式数据流的传输控制

从上一节可知,交互式数据流应用的特点是,每次应用要发送的数据量都比较小(产生的报文分组很小,但每个分组的TCP/IP报文头大小比应用数据本身的大小要大很多,如20字节IP首部+20字节TCP首部+1字节应用数据),当网络中出现了大量的小分组时(网络中有很多用户同时使用应用),这在局域网中通常不会有问题(客户端服务端都部署在局域网中),但在广域网上就很可能会出现问题,中间要经过好几个路由,有可能会造成拥塞(总体TCP/IP报文头大小占了大头)。因此,这时可以考虑采用Nagle算法,通过该算法可以减少分组数目,缓解网络拥塞。

Nagle算法

Nagle算法描述如下:

要求一个TCP连接上最多只能有一个未被确认的分组,在该分组的ACK确认达到之前不能发送其他的小分组。相反,Nagle算法会收集少量的正在等待的小分组,在ACK到来时以一个分组的方式发送出去。(可以理解为打包操作)

该算法是自适应的:ACK达到的越快,数据也就发送得越快;反之ACK到达越慢,数据发送得也就越慢。从这里可以看出,nagle算法可以起到减少分组数量的作用,发送的分组少了,对网络负载的冲击也会相应的降低,从而避免了进一步的拥塞。

但如果在低速的广域网上,对于要求数据实时、低时延传输的应用,就会很可能出现更高的时延(因为本该一次全部发送出去的数据,现在要分批发送,时延就更高了,本来从发送一次报文到相应的ACK回来的这个过程时延就不低。如果接收端触发了经受时延确认算法,则会更恶劣)。具体示例、阐述详见《TCP/IP协议详解 卷1:协议》-“关闭nagle算法”章节。

对于高速的局域网,Nagle算法是否适用?

在以太网上一个字节被发送、确认和回显的平均往返时间约为16ms,按这个速度算,1s可以传输1000/16=62.5个字节。那么如果在局域网中,诸如telnet/terminal这类的程序,就会出现ACK确认都回来了,新的按键数据还没有出现的尴尬情况(手速太慢),因此也就无需nagle算法了,但对于其他应用来说就另说了。

成块数据流的传输控制

对于成块数据流应用,在发送数据时有两种方式:

第一种方式比较少采用,一般是采用第二种方式,那么对于第二种方式,在一次停止等待确认前是不是可以发送任意个分组? 在TCP中,发送端有有限的发送缓存、接收端有有限的接收缓存,发送端与接收端之间可能会经过数个路由,而每个路由又有自身的缓存容量限制,如果发送端发送过多的分组突破了中间路由的缓存上限,那么会出现分组丢弃、网络拥塞,又或者接收端本地已没有足够的空闲缓存空间,这些情况也会造成分组丢弃、继而发送端不得不进行超时重传。因此,需要有合适的方法控制分组进入网络的速率以适应当前网络情况,以及适应接收端的接收能力。从发送端侧实施的流控算法有慢启动、拥塞避免,从接收端侧实施的则有滑动窗口。

滑动窗口WND

滑动窗口:

由接收方控制,接收方根据本地TCP缓存剩余空闲空间多少进行控制 通告 发送方。

可以看出,滑动窗口主要是接收端用于“告诉”发送端,“你下次最多能发送XXX字节数据过来,不能再大啦!”,这是接收段端的流控。

在局域网下,发送方一般可以一直发送多个报文段,直到达到接收方的窗口大小为止。但在广域网下,如果两者之间存在较慢的链路,中间的路由需要缓存分组,则发送过多的分组(虽然没达到滑动窗口大小)有可能出现耗尽路由的缓存、丢弃分组,从而拥塞网络。分组丢失给发送方最直观的指示(表现)是:

TCP根据不同的分组丢失指示执行不同流控策略,如果是“超时”,则接下来发送端执行“慢启动”策略,如果是“收到重复的确认”,则执行“快速重传-快速恢复-拥塞避免”策略;无论执行何种策略,TCP对一个TCP连接维护两个关键变量:

在建立连接后,对CWND初始化为1个报文段,sstresh为65535个字节。当拥塞发生时,设置慢启动阀门sstresh值为当前拥塞窗口cwnd的一半。

慢启动

慢启动算法简要描述如下:

拥塞避免

拥塞避免算法如下:

快速重传

快速重传是在发送方接收到3个或以上的重复ACK时执行的策略,这种情况下没有执行慢启动的原因是 由于收到重复的ACK不仅仅是告诉我们有一个分组已经丢失,还意味着接收端还接收到了该ACK标记的序号以后的报文组,因为接收端只有在接收到另一个报文(断序后面的)才会发送一个重复的ACK,也就是说,在收发两端仍然有流动的数据,此时不希望执行慢启动来突然减少数据流。快速重传和快速恢复算法描述如下:

小结

以上简要总结了TCP交互式数据流、成块数据流的流控机制,其中成块数据流流控的一个核心思想是发送报文组的数量先从1开始缓慢的指数增长(慢启动),然后再加性增长, 直至分组进入网络的速率与回复的速率基本相当。如果拥塞,则根据分组丢失的指示来执行慢启动或快速重传,无论执行何种策略,目的只有一个,那就是将分组进入网络的速率减半以缓解当前的网络拥塞状况。整体梳理一遍,如下图所示:

TCP流控

引用参考

《TCP/IP协议详解 卷1:协议》.W.Richard Stevens

上一篇 下一篇

猜你喜欢

热点阅读