介绍TCP/IP协议中每一层里面的核心内容~
TCP
能够保证可靠传输,但是失去了效率!
但是TCP
希望能够在保证可靠性的前提下,尽可能地提高效率 (但还是UDP
更快)~
滑动窗口就是 提高TCP
传输效率的有效机制!!
主机A大量的时间都消耗在了等待ACK
上~
提升效率的方式就是 : 不等ACK
了!! 直接往下发下一条 ~
确实是不等ACK
了,但是又不是完全不等!
每次批量的发送一波消息,然后再等一波批量的ACK
,再发一波消息~
把不需要等待,就可以直接发送的数据的量,就称为 “窗口大小”
批量发送四条数据,批量等待4条ACK
,此处的窗口大小,就是4000
(以字节为单位算的)
注意:
主机A是收到一个
ACK
,就继续发一条数据,而不是等所有的ACK
都到了,才统一发下一组~
一开始白色的框,表示 给主机B发送了4条数据
1001- 5000
2001
这个ACK
到达主机A的时候,此时主机A就立即发送5001 - 6000
此时A等待ACK
的范围就是2001 - 6000
白色的框,也表示哪些数据在等待确认~
在
2001
这个ACK到达之前,主机A上待确认的数据是1001 - 5000
在2001
到达之后,意思是1001-2000
就确认发送成功了,于是就把1001 - 2000
这个记录从白色的框里删掉了同时又发送了
5001 - 6000
这个数据 因此就需要继续等待5001 - 6000
的ACK
此时要等的数据仍然是4条~
看起来就好像是白色的框 长度没变,往后移了一样
效率高不高取决于窗口大小,窗口越大,效率就越高,窗口越小,效率就越低
假设窗口是 无穷大,此时发送方就完全不需要等待ACK
了,此时效率就和UDP
一样了
刚才讨论的是正常情况下,但是如果出现丢包/乱序 怎么办 ?
丢包:
- 响应的ACK丢了
- 传的数据丢了
此时丢了3个ACK
,但是没关系,不用做任何处理!
对于可靠传输没有任何影响!
因为确认序号表示的是该数据之前的序号都收到了!
比如:
1001表示小于1001的数据到了
2001表示小于2001的数据到了
而后者大于前者,2001
之前的数据到了已经可以证明1001
之前的数据已经到了! 是一个包含的关系~
上图就是" 快速重传 "(搭配滑动窗口机制的超时重传)
如果传输的数据很多,批量传输,此时自然是遵守快速重传的机制
如果传输的数据很少(就只有一条),此时仍然是按照超时重传的方式来进行的
但是窗口可以无限大吗❓ 接收方可以无限接收吗❓
如果发的太块,接收方处理速度跟不上了,就会导致接收方丢弃一部分数据~
TCP
是要保证可靠性的,丢弃的数据TCP
还要重传这些数据
这就让本来就处理不过来的接收方,更接收不过来了…
所以就需要再有其他的机制,来对发送方的发送数据,作出限制!
在滑动窗口的基础之上,对发送速率作出限制的机制!
就是限制发送方的窗口大小不要太大!!
问问接收方,看看接收方,觉得发多快合适~
这是接收方对于发送方的反制~
接收方根据自己的接收能力,来反向影响发送方接下来的发送速率!!
接收方的接收速率,如何进行量化❓
接收方使用接收缓冲区的剩余空间大小,来作为发送方发送速率(窗口大小)的参考数值!!!
接收方B收到A的数据之后,就会在ACK应答报文中,把当前 接收缓冲区剩余空间大小的值,反馈给发送方~
16位能表示的最大数字就是64kb,这是否意味着滑动窗口最大就是64kb呢❓
其实不是!!
TCP
报头的选项中,会有一个特殊的值: 窗口大小的扩展因子
这里是可以通过扩展因子来表示更大的值的!!
流量控制图解:
流量控制,是通过接收方的处理能力,来衡量发送方的速率的~
刚才只是考虑了接收方的处理速率,难道发送方就可以为所欲为的发送了吗❔
显然也不是,还得考虑中间这些转发节点的情况~
如果中间的某个设备出问题了,比如卡了,那这个设备就会限制整体的传输速率,如果还按照大的窗口去发,就很容易产生丢包
接收方的处理速率是容易量化的
但是中间结点的情况难以量化~
❓那如何考虑中间结点的情况呢?
思路:
把中间的这些设备,视为一个"整体" 通过"做实验"的方式,来验证发送速度多少合适!!
开始的时候发的慢点~ 如果一路畅通,就适当的提高一下速度 提高到一定程度,发生丢包~ 再降低一下速度~
降低速度之后,发现又通畅了,那就再提高一下速度~在这样一个反复的提高降低的过程,就达到了一个 “动态平衡”
上述这样的动态调整发送速率的机制,就叫做 " 拥塞控制 "
流量控制,在控制发送方的窗口大小
拥塞控制,也是在控制发送方的窗口大小
当这两个控制的窗口大小不同时,取这两个中小的窗口~
刚才只是简单描述了下拥塞控制思路:
从小的开始,逐渐变大,如果丢包再变小…反复动态调整[宏观策略]
❓TCP实现拥塞控制的具体实现是怎样的呢?
TCP
引入慢启动机制,先发少量的数据 (在发送之初,网络情况前路未知)上述看到的过程是TCP
传统的拥塞控制的(以前是这么搞的)
后来TCP
也在进行演化,拥塞控制也作出了一些改进~
其中的改进就是不再回归到初始值了~
而是回归到一个中间的值~