c++tcp接收⽂件缓存多⼤合适_快速了解TCP的流量控制与拥
塞控制
更多内容,欢迎关注:全菜⼯程师⼩辉~
有关TCP你不能不知道的三次握⼿和四次挥⼿问题,关于三次握⼿与四次挥⼿你要知道这些
流量控制
1. 滑动窗⼝
数据的传送过程中很可能出现接收⽅来不及接收的情况,这时就需要对发送⽅进⾏控制以免数据丢失。利⽤滑动窗⼝机制可以很⽅便地在TCP连接上对发送⽅的流量进⾏控制。TCP的窗⼝单位是字节,不是报⽂段,发送⽅的发送窗⼝不能超过接收⽅给出的接收窗⼝的数值。
TCP规定,即使设置为零窗⼝,也必须接收以下⼏种报⽂段:
零窗⼝探测报⽂段
确认报⽂段
携带紧急数据的报⽂段
确认丢失和确认迟到
持续计时器
存在这样⼀种情况:发送⽅接收到零窗⼝报⽂之后将发送窗⼝设置为0,停⽌发送数据。但等到接收⽅
有⾜够缓存,发送了⾮零窗⼝⼤⼩的报⽂,但是这个报⽂中途丢失,那么发送⽅的发送窗⼝就⼀直为0导致死锁。
为此,TCP为每⼀个连接设有⼀个持续计时器(Persistence Timer):当TCP连接的⼀⽅收到对⽅的零窗⼝通知时就启动持续计时器。若持续计时器时间到期,就发送⼀个零窗⼝探测报⽂段(携有1字节的数据),那么收到这个报⽂段的⼀⽅就在确认这个探测报⽂段时给出了现在的窗⼝值。若窗⼝仍然是零,则收到这个报⽂段的⼀⽅就重新设置持续计时器;若窗⼝不是零,则死锁的僵局就可以打破了。
2. 延迟ACK
如果TCP对每个数据包都发送⼀个ACK确认,那么只是⼀个单独的数据包为了发送⼀个ACK代价⽐较⾼,所以TCP会延迟⼀段时间,如果这段时间内有数据发送到对端,则捎带发送ACK,如果在延迟ACK定时器触发时候,发现ACK尚未发送,则⽴即单独发送;
延迟ACK好处:
1. 避免糊涂窗⼝综合症。
2. 发送数据的时候将ACK捎带发送,不必单独发送ACK。如果延迟时间内有多个数据段到达,那么允许协议栈发送⼀个ACK确认多个报
⽂段。减少流量消耗。
糊涂窗⼝综合症:TCP接收⽅的缓存已满,⽽交互式的应⽤进程⼀次只从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送⽅发送确认,并把窗⼝设置为1个字节(但发送的数据报为40字节的的话)。当发送⽅⼜发来1个字节的数据(发送⽅的IP数据报是41字节),接收⽅发回确认,仍然将窗⼝设置为1个字节。这样,⽹络的效率很低。要解决这个问题,可让接收⽅等待⼀段时间,使得或者接收缓存已有⾜够空间容纳⼀个最长的报⽂段或者等到接收⽅缓存已有⼀半的空闲空间。只要出现这两种情况,接收⽅就发回确认报⽂,并向发送⽅通知当前的窗⼝⼤⼩。此外,发送⽅也不要发送太⼩的报⽂段,⽽是把数据报积累成⾜够⼤的报⽂段,或达到接收⽅缓存的空间的⼀半⼤⼩。
拥塞控制
拥塞控制与流量控制的区别 :
拥塞控制是防⽌过多的数据注⼊到⽹络中,可以使⽹络中的路由器或链路不致过载,是⼀个全局性的过程。
流量控制是点对点通信量的控制,是⼀个端到端的问题,主要就是抑制发送端发送数据的速率,以便接收端来得及接收。
大文件发送拥塞控制的作⽤
拥塞控制是为了防⽌过多的数据注⼊到⽹络中,这样可以使⽹络中的路由器或者链路不⾄于过载。
拥塞控制的算法
我们假定:
1. 数据单⽅向传送,⽽另外⼀个⽅向只传送确认。
2. 接收⽅总是有⾜够⼤的缓存空间,因为发送窗⼝的⼤⼩由⽹络的拥塞程度来决定。
发送⽅的发送窗⼝的上限值应当取为接收⽅窗⼝rwnd和拥塞窗⼝cwnd这两个变量中较⼩的⼀个,即发送窗⼝的上限值为Min[rwnd, cwnd]当rwnd < cwnd时,是接收⽅的接收能⼒限制发送窗⼝的最⼤值
当cwnd < rwnd时,则是⽹络的拥塞限制发送窗⼝的最⼤值
拥塞控制的过程⼀共涉及了4种算法:
1. 慢启动
2. 拥塞避免
3. 快重传
4. 快恢复
1. 慢启动
发送⽅维护⼀个拥塞窗⼝cwnd的状态变量,拥塞窗⼝的⼤⼩取决于⽹络的拥塞程度,动态变化。通过逐渐增加cwnd的⼤⼩来探测可⽤的⽹络容量,防⽌连接开始时采⽤不合适的发送量导致⽹络拥塞。
当主机开始发送数据时,如果通过较⼤的发送窗⼝⽴即将全部数据字节都注⼊到⽹络中,由于不清楚⽹络状况,有可能引起⽹络拥塞。较好的⽅法是试探,从⼩到⼤逐渐增⼤发送端拥塞窗⼝的cwnd数值。
例如:开始发送⽅先设置cwnd=1,发送第⼀个报⽂段M1,接收⽅接收到M1后,ACK返回给发送端,发送端将cwnd增加到2,接着发送⽅发送M2,再次接受到ACK后将cwnd增加到4...慢启动算法每经过⼀个传输轮次,拥塞窗⼝cwnd就加倍。
当rwnd⾜够⼤时,为防⽌拥塞窗⼝cwind的增长引起⽹络拥塞,还需要另外⼀个变量,慢开始门限ssthresh
当cwnd<ssthresh,使⽤慢开始算法
当cwnd=ssthresh,既可使⽤慢开始算法,也可以使⽤拥塞避免算法
当cwnd>ssthresh,使⽤拥塞避免算法
⾸次慢启动的ssthresh值,可以参阅⽹上的各种讨论,限于篇幅,本⽂不作介绍~
2.拥塞避免
控制过程:
1. TCP连接初始化,将拥塞窗⼝cwnd设置为1个报⽂段,即cwnd=1
2. 执⾏慢开始算法,cwnd按指数规律增长,直到cwnd == ssthresh时,开始拥塞避免算法,cwnd按线性规律增长
3. 当⽹络发⽣阻塞,把ssthresh值更新为拥塞前cwnd的⼀半(12=24/2),cwnd重新设置为1,再按照(2)执⾏
让拥塞窗⼝cwnd缓慢地增⼤,每经过⼀个往返时间RTT就把发送⽅的拥塞窗⼝cwnd+1,⽽不是加倍。
这样拥塞窗⼝cwnd线性缓慢增长,⽐慢开始算法的拥塞窗⼝增长速率缓慢地多。
⽆论慢启动开始阶段还是在拥塞避免阶段,只要发送⽅判断⽹络出现拥塞(没收到ACK),就把慢启动门限ssthresh设置为出现拥塞时的cwnd的⼀半。然后把拥塞窗⼝cwnd重新设置为1,执⾏慢启动算法。这样做的⽬的是能迅速的减少主机向⽹络中传输数据,使发⽣拥塞的路由器能够把队列中堆积的分组处理完毕。拥塞窗⼝是按照线性的规律增长,⽐慢启动算法拥塞窗⼝增长快的多。
拥塞避免是由指数增长拉低到线性增长,降低出现拥塞的可能,并不是能完全避免⽹络拥塞
3.快重传
⼀条TCP连接有时会因等待重传计时器的超时⽽空闲较长的时间,慢开始和拥塞避免⽆法很好地解决这类问题,因此提出了快重传和快恢复的拥塞控制⽅法。
为使发送⽅及早知道有报⽂没有达到对⽅,快重传算法⾸先要求接受⽅每收到⼀个报⽂段后就⽴即发出重复确认。快重传算法并⾮取消了重传机制,只是在某些情况下更早地重传丢失的报⽂段。即,当TCP源端收到3个相同的ACK确认时,即认为有数据包丢失,则源端重传丢失的数据包,⽽不必等待RTO(Retransmission Timeout)超时。由于发送⽅尽早重传未被确认的报⽂段。因此,采⽤快重传后可以使整个⽹络吞吐量提⾼20%
快重传算法要求⾸先接收⽅收到⼀个失序的报⽂段后就⽴刻发出重复确认,⽽不要等待⾃⼰发送数据时才进⾏捎带确认。接收⽅成功的接受了发送⽅发送来的M1、M2并且分别给发送了ACK,现在接收⽅没有收到M3,⽽接收到了M4,显然接收⽅不能确认M4,因为M4是失序的报⽂段。如果根据可靠性传输原理接收⽅什么都不做,但是按照快速重传算法,在收到M4、M5等报⽂段的时候,不断重复的向发送⽅发送M2的ACK,如果接收⽅⼀连收到三个重复的ACK,那么发送⽅不必等待重传计时器到期,由于发送⽅尽早重传未被确认的报⽂段。
4.快恢复
快恢复算法控制过程:
当发送⽅连续收到3个重复确认时,发送⽅认为⽹络很可能没有发⽣拥塞,因此不执⾏慢启动。⽽是把cwnd值设为新的门限值,然后执⾏拥塞避免算法,cwnd值线性增⼤,避免了当⽹络拥塞不够严重时采⽤"慢启动"算法⽽造成过⼤地减⼩发送窗⼝尺⼨的现象,这就是快恢复。
更多内容,欢迎关注:全菜⼯程师⼩辉~