努力经营当下,直至未来明朗!
文章目录
- 前言
- TCP相关机制
- 4. 【滑动窗口】
- 5.【流量控制】
- 6.【拥塞控制】
- 总结
前言
一个人最大的痛苦来源于对自己无能的愤怒!
Hi,这里是不想秃头的宝贝儿!
本文主要内容是 传输层中TCP相关机制的补充:滑动窗口、流量控制、拥塞控制。
也很重要!(重点内容会重点标出)
TCP相关机制
4. 【滑动窗口】
-
TCP能够保证可靠传输,但是失去了效率,那么如何尽可能提高传输效率呢?(但是注意:再怎么提高都是无法超过UDP效率的)
滑动窗口:提高TCP传输效率的有效机制 -
没有引入滑动窗口,只是一个朴素的确认应答
主机A大量的时间都消耗在了等待ACK上,则提升效率的方法就是不等ACK了,直接往下继续发送(但其实不是完全不等,而是每次发送一波消息,然后等一波ACK,然后再发送一波消息) -
把不需要等待就可以直接发送的数据的量,称为“窗口大小”
-
滑动窗口下:如图批量发送3条数据,批量接收3条ACK,此处的窗口大小是300(以字节为单位)
注意:主机A是收到了一个ACK就继续发一条数据,而不是等所有的ACK都到了才统一发下一组。
-
滑动窗口示例(具体详细可参考:滑动窗口)
-
TCP传输效率与窗口大小有关:窗口越大,效率越高。(窗口无限大则TCP效率就与UDP一样,但是这样的话TCP的可靠性就无法保证了)
-
如果出现丢包/乱序怎么办?
① 传输的数据报丢了:应答ACK会一直索要未接收到的部分,几次之后主机A就会对丢失的数据报进行重传,没丢失的包不进行重传(没有任何重复的工作),而此时B补齐了空缺,接收到了所有已经传输过来的数据。–》快速重传(搭配滑动窗口机制的超时重传)
② 应答ACK丢了:没有任何影响,因为后面ACK到达就说明前面的所有都已经到达了。
但是不是说有了快速重传,超时重传就没有意义了:
① 当传输的数据很多的时候进行批量传输,此时就遵守快速重传方式;
② 但是如果传输的数据很少(如只有一条),那么此时仍然是按照超时重传的方式来进行的。
- 窗口越大发送速度其实就会越快,但是窗口能够无限大吗?
发送速度如果过快,而接收方的处理速度跟不上了,就会导致接收方丢弃一部分数据,TCP是要保证可靠性的,所以TCP还得重传这些数据,这就会让本就不富裕的接收方雪上加霜。
此时就需要其他机制来对发送方的发送速度作出限制:
【流量控制机制】
5.【流量控制】
- 在滑动窗口基础上对发送速率作出限制的机制,其实就是在限制发送方的窗口不要太大,尽量保持在一个合适的大小。
- 那么发送方的窗口大小多大才是合适的呢?
接收方对发送方进行反制,接收方根据自己的接收能力来反向影响发送方接下来的发送速率。 - 那么接收方的接收速率如何进行量化呢?
接收方使用内核的接收缓冲区的剩余空间大小来作为发送方发送速率(窗口大小)的参考数值!
(此处补充:UDP是只有接收缓冲区,没有发送缓冲区的) - 接收方B在收到发送方A的数据之后就会在ACK应答报文中把当前缓冲区剩余空间大小的值反馈给发送方,存储在TCP的16位窗口大小中。这个字段只在ACK为1的时候有效,否则该字段无效。
16位能表示的最大数就是64Kb,那么是否意味着滑动窗口最大就是64kb呢?
其实不是,在TCP报头的“选项”中会有一个特殊的值叫“窗口大小的扩展因子”,是可以通过扩展因子来表示更大的滑动窗口大小值的。
-
流量控制过程
① 窗口大小是动态变化的,每次ACK之后都会调整窗口大小
② 如果此时窗口大小变为0,也就是告诉发送方先别发送,但是如果主机A不进行数据发送,则B没法应答ACK,如果B不应答ACK,则后续缓冲区里有空闲空间时如何告知主机A呢?
主机A会发送一个探测报文,该报文长度只有1,不携带任何业务数据(不带载荷),只是探测一下窗口大小应该为多少,也就是为了B能够返回ACK来告知A其窗口大小。(探测报文是周期性发送,不是立即发送) -
流量控制:是通过接收方的处理能力来衡量发送方的速率的。
-
以上所述只是考虑了接收方的处理速率,但是我们还是需要考虑中间这些转发节点的情况(类似于木桶原理)。接收方的速率容易量化,但是中间节点的情况难以量化。所以,如何考虑衡量中间节点的情况呢?
思路:把中间的这些设备视为一个“整体”,通过“做实验”的方式来验证发送速度多少合适,即从小的开始发送,进行“提速丢包则降速,降速畅通则提速”的循环,以达到“动态平衡”。(网络环境不是一成不变的)
也就是【拥塞控制】来衡量中间转发结点的处理速率。
- 拥塞控制和流量控制都是在控制发送方的窗口大小,实际最后决定窗口大小是【谁小听谁的】!(也就是速度慢的决定)
6.【拥塞控制】
- TCP实现拥塞控制的具体方式是啥?
① TCP引入慢启动机制,先发少量的数据(因为发送之初,网络情况未知)
② 如果不丢包,就需要放大拥塞窗口(拥塞控制下的那个窗口的大小),开始的时候先指数增长(翻倍),达到阈值之后线性增长。
【指数增长可以在短时间内摸清楚网络承载的底线,而为了防止翻倍太快一下超过上限就设置一个阈值,达到阈值之后就不再指数增长,转为线性增长】
(初始阈值一般是系统配置的。)
当速率达到上限就会出现网络拥堵,从而出现丢包;此时窗口大小一下子会回到最初的值,重复刚才的指数增长+线性增长,并且要动态调整阈值,阈值调整为刚才丢包的窗口的一半。
- TCP后来也对拥塞控制做了一些改进,不是直接回归到初始值,而是回归到一个比较折中的值,具体该值的决定策略不再研究。
注:TCP相关的机制还没有介绍完,详见下篇博客
总结
- 滑动窗口:尽量提高传输效率
- 流量控制:通过接收方来进行反制
- 拥塞控制:中间的转发结点【注意图】