TCP的流量控制

1、利用滑动窗口的流量控制

  一般来说,我们总希望数据传输的更快一些。但如果发送方把数据发得过快,接收方就可能来不及接收,这就会造成数据的丢失。流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收。
  利用滑动窗口机制可以很方便地在TCP连接上实现发送方流量控制。通过接收方的确认报文中的窗口字段,发送方能够准确地控制发送字节数。

2、TCP传输效率

2.1、MSS

  TCP维持一个持续变量,他等于最大报文段长度MSS(类似以太网协议中的MTU值)。只要缓存中存放的数据达到MSS字节时,就组成一个TCP报文段发送出去。当数据长度超过MSS值,就会根据MSS值分多次进行传输,叫做分段(与IP层分片相似)。

2.2、Nagle

  TCP发送报文的时机是一个较为复杂的问题。为了提高传输效率,在TCP的实现中广泛使用Nagle算法。算法如下:若发送应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对后面的数据先进行写入缓存。只有收到对签名一个报文段的确认后才继续发送下一段报文。

2.3、粘包现象

  TCP黏包是指发送方的若干包数据到接收方时粘成一个包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
  TCP默认使用Nagle算法计算发送数据时机。Nagle算法上面说过,会收集多个小分组先写在缓存中,当收到确认时一起发送。TCP接收到分组时,应用层并不一定会立即处理。前面滑动窗口提到过TCP会将收到的分组保存在接收缓存中,应用程序主动从缓存里读到报文分组内容。如果TCP接收分组的速度大于应用程序读取分组的速度,多个数据包就会被存至缓存,应用程序读时,就会读到多个首尾相接粘到一起的包。

3、拥塞控制

  前面的流量控制是避免发送方的数据填满接收方的缓存,但并不知道网络中发生了什么。一般来说,计算机网络都处在一个共享的环境。因此也有可能会因为其他主机之间的通信使得网络拥堵。在网络出现拥堵时,如果继续发送大量的数据包,可能会导致数据包时延、丢失,这时 TCP 就会重传数据,但是⼀重传就会导致⽹络的负担更重,于是会导致更⼤的延迟以及更多的丢包,这个情况就会进⼊恶性循环被不断地放⼤…
  于是,就有了拥塞控制,控制的⽬的就是避免「发送⽅」的数据填满整个⽹络。为了在「发送⽅」调节所要发送数据的数据量,定义了⼀个叫做「拥塞窗⼝」的概念。拥塞窗⼝ cwnd是发送⽅维护的⼀个的状态变ᰁ,它会根据⽹络的拥塞程度动态变化的。

我们在前⾯提到过发送窗⼝ swnd 和接收窗⼝ rwnd 是约等于的关系,那么由于加⼊了拥塞窗⼝的概念后,此时发送窗⼝的值是swnd = min(cwnd, rwnd),也就是拥塞窗⼝和接收窗⼝中的最⼩值。
拥塞窗⼝ cwnd 变化的规则:
只要⽹络中没有出现拥塞, cwnd 就会增⼤;
但⽹络中出现了拥塞, cwnd 就减少;

只要「发送⽅」没有在规定时间内接收到 ACK 应答报⽂,也就是发⽣了超时重传,就会认为⽹络出现了⽤拥塞。

3.1、拥塞控制四个算法

  慢启动(slow-start)、拥塞避免(congestion avoidance)、快重传(fast retransmit)、快恢复(fast recovery)。
慢启动
  TCP 在刚建⽴连接完成后,⾸先是有个慢启动的过程,这个慢启动的意思就是⼀点⼀点的提⾼发送数据包的数量。慢启动的算法规则:当发送⽅每收到⼀个 ACK,拥塞窗⼝ cwnd 的⼤⼩就会加 1。

连接建⽴完成后,⼀开始初始化 cwnd = 1 ,表示可以传⼀个 MSS ⼤⼩的数据。
当收到⼀个 ACK 确认应答后,cwnd 增加 1,于是⼀次能够发送 2 个
当收到 2 个的 ACK 确认应答后, cwnd 增加 2,于是就可以⽐之前多发2 个,所以这⼀次能够发送 4 个
当这 4 个的 ACK 确认到来的时候,每个确认 cwnd 增加 1, 4 个确认 cwnd 增加 4,于是就可以⽐之前多发 4
个,所以这⼀次能够发送 8 个。

  可以看出慢启动算法,发包的个数是指数性的增⻓。有⼀个叫慢启动⻔限 ssthresh (slow start threshold)状态变量。

当 cwnd < ssthresh 时,使⽤慢启动算法。
当 cwnd >= ssthresh 时,就会使⽤「拥塞避免算法」。

拥塞避免
  前⾯说道,当拥塞窗⼝ cwnd 「超过」慢启动⻔限 ssthresh 就会进⼊拥塞避免算法。⼀般来说 ssthresh 的⼤⼩是 65535 字节。那么进⼊拥塞避免算法后,它的规则是:每当收到⼀个 ACK 时,cwnd 增加 1/cwnd。
  接上前⾯的慢启动的栗⼦,现假定 ssthresh 为 8 :

当 8 个 ACK 应答确认到来时,每个确认增加 1/8,8 个 ACK 确认 cwnd ⼀共增加 1,于是这⼀次能够发送 9个 MSS ⼤⼩的数据,变成了线性增⻓。

  拥塞避免算法就是将原本慢启动算法的指数增⻓变成了线性增⻓,还是增⻓阶段,但是增⻓速度缓慢了⼀些。
快重传
  当⽹络出现拥塞,也就是会发⽣数据包重传,重传机制主要有两种:超时重传、快速重传。
  超时重传之前的总结中有介绍过,此处只说一下快速重传。「快速重传算法」。当接收⽅发现丢了⼀个中间包的时候,发送三次前⼀个包的ACK,于是发送端就会快速地重传,不必等待超时再重传。

TCP 认为这种情况不严᯿,因为⼤部分没丢,只丢了⼀⼩部分,则 ssthresh 和 cwnd 变化如下:
cwnd = cwnd/2 ,也就是设置为原来的⼀半;
ssthresh = cwnd ;

快恢复
  快速重传和快速恢复算法⼀般同时使⽤,快速恢复算法是认为,你还能收到 3 个᯿复 ACK 说明⽹络也不那么糟糕,所以没有必要像 RTO 超时那么强烈。进⼊快速恢复之前, cwnd 和 ssthresh 已被更新了:cwnd = cwnd/2 ,也就是设置为原来的⼀半;ssthresh = cwnd ;
  快速恢复算法如下:

拥塞窗⼝ cwnd = ssthresh + 3 ( 3 的意思是确认有 3 个数据包被收到了);
重传丢失的数据包;
如果再收到重复的 ACK,那么 cwnd 增加 1;
如果收到新数据的 ACK 后,把 cwnd 设置为第⼀步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说
明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进⼊
拥塞避免状态;

在这里插入图片描述

  • 16
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值