TCP的流量控制和拥塞控制

一、首先和UDP作比较谈谈TCP的特点

(1)UDP是数据报协议,每个数据报都有长度,数据报的长度和数据一起发送和接受,各个数据报的发送和接受相互独立,互不影响。而TCP是字节流协议,所有经TCP发送的数据没有记录边界。

(2) UDP是无连接、不可靠的协议,而TCP是有连接,可靠协议。TCP的可靠性主要指经TCP发送的数据要么准确无误的发送到了对端,要么发送失败并且以合适的方式通知应用程序,也就是可靠的传输数据和可靠地报告错误,TCP协议每一次发送数据以后先暂时将数据保存在缓存区,直到接收到对端的ACK然后将缓存区中已发送的数据清除或者因为等待ACK超市而重新发送,如果重新发送多次后任未成功发送,TCP将通知应用程序数据发送失败。同时TCP为每次发送的数据进行编号,到对端接收到数据后TCP会按照编号有序上传到应用。而UDP则既不对接收的数据进行确认,也不会对发送的数据进行编号以保证按序到达。

(3)TCP有流量控制和拥塞控制,TCP的流量控制可以随时告知对端他自己的缓冲区可以容纳多少数据,已让对端控制数据发送速度,以免淹没本地缓冲区,TCP使用滑动窗口来实现流量控制。而UDP对于超出缓冲区容量的数据则直接丢弃。TCP的拥塞控制是为了防止过多的数据拥入网络,造成数据链路的负载过大而使得整个网络的传输效率过低。

(4)由于TCP需要重传、拥塞控制、流量控制等机制,所以TCP的实现在kernel内维护一个发送缓冲区,一个接受缓冲区,在TCP协议的socket fd上调用write/send等发送函数,返回成功只表明数据成功复制到了TCP的发送缓冲区,并不能表明数据成功发送到了对端。如果成功发送到TCP缓冲区的数据在发送到对端的过程中出现错误,TCP会在随后的调用中通知应用程序。而UDP发送成功则是指成功发送到了链路层.

(5)既然TCP协议在kernel内维护了一个发送缓冲区,那么这个缓冲区内的数据什么时候会正真被发送呢?这是有Nagle算法来控制的。具体的来说:

<1>.缓冲区中的数据达到MSS

<2>.设置了NODELAY选项

<3>.该包含有FIN

<4>.所有已发送的数据包均已得到确认(未设置TCP_CROCK时)

<5>.发生了超时

(6)TCP/IP中不仅仅有nagle算法,还有一个TCP确认延迟机制 。当Server端收到数据之后,它并不会马上向client端发送ACK,而是会将ACK的发送延迟一段时间(假设为t),它希望在t时间内server端会向client端发送应答数据,这样ACK就能够和应答数据一起发送,就像是应答数据捎带着ACK过去。这也就意味着服务器如果只接受数据不发送数据,那么对接收到的数据确认会延迟较长一段时间(TCP在等待数据以便和ACK一起发送),而客户端在这段时间由于没有接收到上一个数据包的ACK,因此根据Nagle算法也会一直等待。 当然,TCP确认延迟并不是一直不变的,TCP连接的延迟确认时间一般初始化为最小值40ms,随后根据连接的重传超时时间(RTO)、上次收到数据包与本次接收数据包的时间间隔等参数进行不断调整。另外可以通过设置TCP_QUICKACK选项来取消确认延迟。

(7)TCP_CORK
选项:所谓的CORK就是塞子的意思,形象地理解就是用CORK将连接塞住,使得数据先不发出去,等到拔去塞子后再发出去。设置该选项后,内核会尽力把小数据包拼接成一个大的数据包(一个MTU)再发送出去,当然若一定时间后(一般为200ms,该值尚待确认),内核仍然没有组合成一个MTU时也必须发送现有的数据(不可能让数据一直等待吧)。

  然而,TCP_CORK的实现可能并那么完美,CORK并不会将连接完全塞住。内核其实并不知道应用层到底什么时候会发送第二批数据用于和第一批数据拼接以达到MTU的大小,因此内核会给出一个时间限制,在该时间内没有拼接成一个大包(努力接近MTU)的话,内核就会无条件发送。也就是说若应用层程序发送小包数据的间隔不够短时,TCP_CORK就没有一点作用,反而失去了数据的实时性(每个小包数据都会延时一定时间再发送),实际上TCP_CROK选项一般在传输文件时用的多一些,其他地方很少见用。

二、TCP流量控制的原理:

从图中可以看出,该TCP的接收窗口为500字节(因为第一次rwnd是以500字节为至的),同时可以看出每次对接收数据的ack发送同时发送了rwnd,而且rwnd在实时变化,也就是所谓的滑动窗口。可以看到B向A的确认中,ack=501哪一项的rwnd=100,也就是说之前接收到的1-500字节中1-100字节数据已被应用程序读取,从而空出100字节的缓冲区,而101-500字节的数据仍然在缓冲区。同时到ack=601的时候,101-600字节共500字节的内容仍然在缓冲区内,填满了整个缓冲区,所以rwnd=0。这儿有个问题,此时A接收到B的rwnd=0,因此不会再向B发送数据,而B把所有缓冲区的数据都处理完了,在等待A新的数据到达,这会造成A和B之间的死锁。TCP的解决方案是,A收到B的rwnd=0时启动定时器,定时器时间到达后A会向B发送一个窗口探测报文段(经携带一字节数据),B收到这个报文段对A确认时就发送了新的rwnd,从而避免了死锁。

二、TCP的拥塞控制:

(1)慢开始和拥塞避免

如果一个新的连接刚建立成功就向网络中发送大量的数据包,很可能会导致网络中路由器缓存不够用(路由器缓存不够用时就会将超出其缓存的数据包丢包,而TCP又要重传该包,可想而知很快会导致网络出现严重拥塞,实际上网络中传输的大部分是路由器由于缓存不够而丢掉导致重复传输的包),所以一开始建立的新连接不能发送大量报文,而是先从一个较低的起点开始发送,如果发送得到及时确认,那么就将这个起点增大一点。

发送方维护着一个拥塞窗口(cwnd),拥塞窗口的大小随着网络负载的变化而实时变化,发送方每次发送数据的大小不得大于拥塞窗口和对端接受窗口的最小值。

这里图方便以报文段大小为单位说明TCP的拥塞控制,实际上是以字节为单位的。

发送发每发送成功一字节就把窗口cwnd加1,这样其实我们注意到发送窗口是以2的指数增长的,所谓乘性增。因此,说是慢开始指得是刚开始发送的初始窗口比较小,但是如果网络通畅的话,发送窗口的增长速度实际上是相当快的。

如果一直以这样的速度增长下去最终也会造成网络拥塞,所以TCP除了cwnd意外还设置了一个慢开始门限ssthresh变量。

当cwnd < ssthresh的时候使用慢开始算法,当cwnd>ssthresh时使用拥塞避免算法。拥塞避免算法是每经过一个RTT的时候就将cwnd加1(注意到这里,慢开始算法是每发送成功一字节就把cwnd加1,经过RTT发送成功了多少字节就增加了多少字节,也就是发送的字节数*2,而拥塞避免算法则不管发送成功多少字节都仅将cwnd加1),此时cwnd的变化开始平缓。无论是在慢开始阶段还是在拥塞避免阶段,只要网络发生拥塞(判断的依据是丢包),都将慢开始门限ssthresh减小为原来的一般并将发送窗口cwnd置为1,执行慢开始算法。

(2)快重传和快恢复

我们知道TCP在发送一个数据包后会设置一个定时器,如果这个定时器到时后仍然没有接受到对端的确认,那么就确认该报文已丢失需要重新发送,但是如果每个已丢失的报文都需要等到定时器到达在重新发送那么传输效率势必会造成影响。因此TCP采用快重传来使得TCP拥有更高效的传输速率。快重传的意思是指接受方没接受到一个失序的报文就立即确认该报文,而不是采用上文所讲的延时确认。当接收方连续接收到三个失序的确认报文后就马上重新发送导致失序的那个报文(这个报文未被确认而导致收到了三个失序的确认报文),而不必等待重传定时器到时。

配合快重传算法的还有快恢复算法,当发送方连续收到三个重复的确认报文时就采用快恢复算法。此时先把sthresh减半,cwnd设置为sthresh相同大小,同时执行拥塞避免算法。注意到此次并未将cwnd置为1,因为TCP认为能够连续收到三个确认报文,所以网络可能并不拥塞,因此只采用了快恢复算法。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 22:16:18

TCP的流量控制和拥塞控制的相关文章

TCP的流量控制与拥塞控制小结

概述 为了提高信道的利用率TCP协议不使用停止等待协议,而是使用连续ARQ协议,意思就是可以连续发出若干个分组然后等待确认,而不是发送一个分组就停止并等待该分组的确认.其中TCP的流量控制与拥塞控制是TCP在数据传输过程俩个重点机制,为TCP有效数据传输立下汗马功劳,这部分也是面试网络协议重点所在,下面从以下俩大方面总结一下 [1]流量控制 [2]拥塞控制 1.流量控制 流量控制:指点对点通信量的控制,是端到端正的问题.流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收. 在T

快速了解TCP的流量控制与拥塞控制

有关TCP你不能不知道的三次握手和四次挥手问题,点我跳转 流量控制 1. 滑动窗口 数据的传送过程中很可能出现接收方来不及接收的情况,这时就需要对发送方进行控制以免数据丢失.利用滑动窗口机制可以很方便地在TCP连接上对发送方的流量进行控制.TCP的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值. TCP规定,即使设置为零窗口,也必须接收以下几种报文段: 零窗口探测报文段 确认报文段 携带紧急数据的报文段 确认丢失和确认迟到 持续计时器 存在这样一种情况:发送方接收

TCP的流量控制

TCP协议作为一个可靠的面向字节流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现. 要区分TCP的流量控制和拥塞控制: 流量控制是发送方的发送数据的速度不能太快,要考虑到接收方的接收缓冲区的大小,不然数据发送的太快,就可能导致接收方的接收缓冲区数据溢出.所以在流量控制中发送方的发送窗口大小受接收方的接收缓冲区的大小的制约. 拥塞控制是发送方根据当前网络的拥塞程度调整自己的发送窗口的大小.当网络出现拥塞的时候,减少发送数据的数量,当网络空闲的时候,

TCP流量控制和拥塞控制

TCP的流量控制 所谓的流量控制就是让发送方的发送速率不要太快,让接收方来得及接受.利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制.TCP的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值. 如图所示,说明了利用可变窗口大小进行流量控制.设主机A向主机B发送数据.双方确定的窗口值是400.再设每一个报文段为100字节长,序号的初始值为seq=1,图中的箭头上面大写ACK,表示首部中的却认为为ACK,小写ack表示确认字段的值. 接收方的主机B进行了

流量控制与拥塞控制学习小结

相同点:都要对发送方进行限制.目的都是提高网络性能.这个没什么好说的. 下面说说不同点: 拿说话举例子.流量控制是控制你说话速度.而拥塞控制是不允许太多人同时说话.为什么呢? 1.流量控制(控制速度):你说得太快了,我有可能漏听. 在点对点的传送过程中,由于发送方和接收方对数据的发送/接收的处理能力不相同,可能会导致发送方发的太快,接收方漏接了/丢弃了许多数据. 2:拥塞控制(控制数量):太多人说话了,我处理不过来.而且同时说话声音会有干扰.我听不懂你们还得重新再说一遍. 注意:拥塞控制不只是点

【网络】TCP的流量控制

一.利用滑动窗口实现流量控制 流量控制是让发送方的发生速率不要太快,要让接收方来得及接收. 发送方的发送窗口不能超过接收方给出的接收窗口的数值,TCP的窗口单位是字节,不是报文段. TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器.若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值,如果窗口仍然是零,那么收到这个报文段的一方就重新设置持续计时器.如果窗口不是零,那么死锁的僵

【转】TCP/IP 系列之 TCP 流控与拥塞控制(一)

原文地址:http://mrpeak.cn/blog/tcp-flow-control00/ TCP/IP 系列之 TCP 流控与拥塞控制(一) TCP 流控(flow control)与拥塞控制(congestion control),是我个人认为每个 iOS 工程师都应该熟悉的,价值含量极高的知识点.明白了三次握手,但是不了解流控和拥塞控制背后的设计原理,是不能够在简历上写「精通 tcp/ip」的. Flow control 和 congestion control 的学习价值高,而且学习过

TCP详解(3):重传、流量控制、拥塞控制……

数据传输 在TCP的数据传送状态,很多重要的机制保证了TCP的可靠性和强壮性.它们包括:使用序号,对收到的TCP报文段进行排序以及检测重复的数据:使用校验和来检测报文段的错误:使用确认和计时器来检测和纠正丢包或延时. 在TCP的连接创建状态,两个主机的TCP层间要交换初始序号(ISN:initial sequence number).这些序号用于标识字节流中的数据,并且还是对应用层的数据字节进行记数的整数.通常在每个TCP报文段中都有一对序号和确认号.TCP报文发送者认为自己的字节编号为序号,而

TCP流量控制与拥塞控制

 一.TCP建立连接后,通信双方都同时可以进行数据的传输:在保证可靠性上,采用超时重传和捎带确认机制:在流量控制上,采用滑动窗口协议,协议中规定,窗口内未经确认的分组需要进行重传:在拥塞控制上,采用慢启动算法. (一)拥塞控制: 1. TCP慢启动.拥塞避免.快速重传.快速回复 为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制.最初由V. Jacobson在1988年的论文中提出的TCP的拥塞控制由"慢启动(Slow start)"和"拥塞避免(Congestio