本篇是介绍部分TCP的特性,了解TCP提高传输速率的机制;如有错误,请在评论区指正,让我们一起交流,共同进步!
TCP在保证可靠性的同时,也要保证效率;
为什么引入滑动窗口?
如果客户端一个一个syn(申请连接), 就需要花大量的时间去等待ack(应答报文),想要提高效率,就需要批量发送数据了;
此时就引入了滑动窗口;
滑动窗口:批量传输数据;窗口中是等待的数据;(批量传输数据,等待多个ack)
滑动窗口的限制:虽然滑动窗口可以批量发送数据,但不是无限发送数据,等到一定的程度,就需要等待ack;等到一个ack就立即发送下一条数据,相当于保证滑动窗口的大小不变(批量等待的数据是一定的,少了就加,多了等待);
窗口滑动:
下图当收到2001这个应答报文,相当于确认收到2001之前的数据,此时会立即发送下一段数据5001-6001;
效率建立在可靠性的基础上,批量发送数据时,可能会出现丢包现象;
前提:批量传输数据的时候;
① ack应答报文丢失
这个情况,对可靠性没有任何影响;
这里就体现了确认序号的意义:确认序号表示,在该序号之前的数据都已经收到;后面的ack传输过去,表示前面的数据已经收到了,所以前面的ack丢了没有任何影响;
② 数据丢失
这里使用了快速重传;
当发送方主机A的部分传输数据丢失,接收方主机B会多次索要丢失的这部分数据,当主机A连续收到主机B索要的数据信息,就会重传这部分数据;
上图中接收缓冲区:当发送方数据丢失,接收方多次向发送方索要数据,发送方才会重传丢失的数据;在发送方重传之前,因为时批量发送数据,剩余数据依然会向接收方发送数据;所以当重传之后,接收方向发送方索要601开始的数据;
为什么引入流量控制呢?
虽说滑动窗口越大,批量发送的数据越多,速度就越快,但并不是越快越好,如果发送的数据瞬间充满接收缓冲区,接下来继续发送,此时数据就会丢包;所以引入了流量控制,限制数据的传输;
流量控制:让接收方来限制发送方的速度;(缓冲区满了,会阻塞等待)
流量控制如何控制呢?
在ack报文中会携带一个16位窗口大小的字段,里面的值就是建议发送方发送的窗口大小;
【注】URG,ACK,PSH,RST,SYN,FIN这6位是特殊的标志位,当它们为1时,对应的报文就会生效;这里是ack报文生效,里面的值就是建议发送方发送的窗口大小;
接收方如何计算窗口大小?
窗口大小 = 接收缓冲区的剩余空间;(发送方根据接收方返回的窗口大小,批量发送数据)-> 这里只是一部分,其实还需要拥塞控制;
图示:
流量控制的发送过程:
① 发送方首先发送一小部分数据,等待接收方的应答报文,此时会知道接收缓冲区的剩余空间,下次发送就会使用滑动窗口批量发送;
② 等到接收缓冲区满了,发送方会暂停发送;
③ 发送方暂停发送后,每隔一段时间会发一个窗口探测报文,如果这期间应用程序使用从socket读取数据,消费接收缓冲区内容,探测报文不在是0,此时发送方就可以继续发送数据;(满了,每隔一段时间探测,等待消费,接收缓冲区不在满了,就继续 发送)
【注】探测报文:不发送数据,但是探测接收缓冲区是否满了,不满就发送,满了隔一段时间继续探测;
这样只是单独把接收缓冲区的剩余空间作为滑动窗口大小进行发送数据,实际还需要考虑拥塞控制;
实际发送方的窗口大小 = min(流量控制窗口 , 拥塞窗口);
流量控制窗口:根据接收缓存取计算出来的;
拥塞窗口:拥塞控制实验出来的;
为什么引入拥塞控制?
从A发送消息到B,不是直接通信,中间需要经过很多节点(路由器,交换机等),也需要考虑这些中间节点的处理能力,所以引入拥塞控制;
如果中间的某个节点出现问题,对整体传输速率有影响,所以需要拥塞控制;
拥塞控制:衡量 中间节点 / 路径 的传输能力;
如何计算拥塞控制的发送速率呢?
数据从A传输到B,每次走到路径都不相同,不能够算出一个具体的值;只能通过实验的方式,找到一个合适的发送速率;而这个发送速率其实是一个动态平衡的状态;
拥塞控制这样的动态平衡状态适应了网络拥堵的情况;
拥塞窗口变化的执行过程:
① 首先给一个较小的初始窗口;
② 窗口先开始指数增长,短时间到达阈值(当前网络传输路径能力的较大值);
③ 窗口再线性增长,增长到一定程度,到达当前路径传输上限,开始丢包;(线性增长是为了逐渐接近路径传输的上限,因为指数增长太快了)
④ 窗口会再次回归到一个比较小的初始值,再次重复上述过程,但是指数增长的阈值会比之前的阈值小;
图示:
【注】
x轴传输轮次: 第几次发送;
y轴拥塞窗口:按照多大的速率发送数据;(不考虑流量控制)
慢开始:开始传输初始值给较小的窗口,相当于传输的速度慢;(当前网络情况未知,所以先给较小的窗口即可,给大了,可能更堵)
网络拥堵:达到路径传输上限;
延时应答:发送ack的时候,稍微延时再发送, 此时接收方的应用程序,会消费接收缓冲区中的数据,此时返回的窗口大小就会大一点,就可以提高传输效率;
为什么延时应答可以提高传输效率呢?
接收方中存在接收缓冲区,在发送方一直向接收方发送数据;
接收方会做出两种选择:
① 立即返回ack应答报文,设此时应答报文中窗口大小为n;
② 延迟一会在返回ack应答报文,在延迟的时候,会消费接收缓冲区里的数据,此时返回的窗口大小大概率大于n;
捎带应答:基于延迟应答;
例如:四次挥手,通过捎带应答就变成了三次挥手;
ack 与 response 时机不同,但通过延时应答,ack就会等待一会再发送,就可能会和 response 合并成一个数据报一起发送;
出现的问题:粘包问题;
粘包问题:
A向B连续发送多个应用层数据报后,这些数据都堆积在B的接收缓冲区中,数据都挨在一起,区分不了一个完整的数据报;
如果此时B在读取数据时,就可能读取半个报等情况;
解决方式:自定义应用层协议
① 定义分隔符,区分每个数据报;
② 约定长度,这个长度就是完整数据报的长度,每次读取固定长度即可;
前提:两端正在进行通信,出现的异常情况;
① 进程关闭 / 崩溃
进程关闭,socket是文件也关闭,进程关闭了但连接还存在,仍可以四次挥手;-》属于正常关闭,不影响;
② 主机关机 - 开始菜单中的关机
关闭所有进程,会触发四次挥手;如果四次挥手没有执行完,就关闭主机了,对端会超时重传,如果没反应ack, 就重置连接,再没反应,就释放连接;
③ 主机掉电 - 拔电源 - 瞬间
主机瞬间关闭,来不及四次挥手操作;
1)对端是发送方:
对端收不到ack, 先超时重传 -》再重置连接 -》最后释放连接;
2)对端是接收方:
对端不知道发送方是没发送数据,还是直接挂了;
使用了TCP内置的心跳包保活机制:特点
i) 周期性,定期发送与定期回应;
ii) 没心跳,挂了就释放连接;
④ 网线断开 与 主机掉电情况一样;
✨✨✨各位读友,本篇分享到内容如果对你有帮助给个赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!