一、拥塞控制💛
总的传输效率,是一个木桶效应,取决于最短板
A和B连接的时候,很多交换机/路由器,中间如果某个环节,转发能力特别差,此时A的速度就不应该超过这里的阈值。
所以,所以我们并不对对中间设备的转发能力进行量化,把中间设备都看成一个整体,而是采取‘实验’的方式,动态调整(工程师思维,一个一个慢慢试,看看哪个好使),产生一个合适窗口大小,
1.使用较小的窗口传输,如果传输通畅,会调大窗口,
2.使用较大的窗口传输,如果传输丢包(不通畅),就调小窗口
二、拥塞窗口 💙
在拥塞控制机制之下,采用的窗口大小,
TCP中拥塞控制,具体这样展开。
1.慢启动:开始进行通信的时候,会使用是一个非常小的窗口,先试试水(看一看当前线路,如果网络堵塞,一上来搞了一个小的,也不影响什么。(如果网络拥堵,一上来搞了一个很大的流量,就让(原本网络不通畅的环境,本来不富裕的条件,雪上加霜🌝🌝)
2.指数增长:在传通畅的过程中,拥塞窗口会指数级增长(*2)
3.线性增长:指数增长,当拥塞窗口达到一个阈值之后,就会从指数级增长,转换成线性增长(y=kx,这种,每次固定+n)这里的指数增长和线性增长:都是按传输的轮次(你交互完成一次,就是一个轮次),现按照传输的轮次,现给窗口定一个大小比如说4000,发出去之后,这一轮完事了,当收到ACK的之后,继续往下发数据。(当然也不会无限增长,增长到一定程度,接近网络传输极限,就可能会出现丢包)
4.拥塞窗口重新回到小窗口:当窗口大小增长的过程,如果使传输出现丢包,认为当前网络出现了作用,此时就会把当前窗口大小调整出最初的小窗口,继续回到之前的套路,->指数增长->线性增长,当然我们还是要根据当前出现丢包的窗口大小,去调整阈值。
拥塞窗口,就是在这个过程中,不断的进行变化,不断的调整的过程,(这样的调整可以更好的适应多变的网络环境,当然也会有不少的性能损失,每次回到慢开始这里,都会使传输速度大打折扣,因此,拥塞控制这里后续诞生一些优化算法(尽可能小窗口窗口传输时间缩短),实际发送方窗口=min(拥塞窗口,流量控制窗口)
(拥塞控制和流量控制),共同限制了滑动窗口机制,可以使用滑动窗口,能够在可靠性大前提下,提高传输的效率(保证可靠性机制)
三、携带应答💜
基于延迟应答,让数据合并
能合并的原因,一方面时间上是可以同时的,另一方面ACK数据本身不需要携带载荷和正常的返回响应的信息不冲突
完全就可以让这个数据报既能携带载荷数据,又能带有ACK的信息(ACK标志,窗口大小,确认序号)
四、粘包问题❤️
这里粘的是指‘应用层数据报’
通过TCP read/write的数据,都是TCP报文的载荷,也就是应用层数据,发送方一次性是报文的载荷,也就是应用册层数据。
发送方一次性可以发送多个应用册数据报的,但接收的时候,如何区分,从哪里得到一个完整的数据报?如果没有设计好,接收方难以区别,甚至会有BUG.
发送两个,半个,一个半都可能出现问题
接收方应用程序,读取这里的数据,read可能是一次一个字节,若一次若干个字节,没办法,一次读一个应用层数据。
做法:合理设计应用层协议,传输层这方面没有办法,需要站在应用层角度,来解决问题。
方法1:应用层协议引入分隔符
使用\n约定包之间分隔符
方法2:应用层协议引入包长度
粘包问题——只要是面向字节流机制都会存在这个问题(文件也有同样的粘包问题,解决的方案也是大同小异,分隔符或者好似长度)
五、TCP异常情况的处理💚
网络本身就会存在一些变数,导致TCP连接不能正常工作了。
(1)进程崩溃
进程就直接没了->PCB没了->文件描述符表也被释放了,相当于调了socket.close()->socket在系统内核中也是一个文件,也会放到文件描述符表中。->崩溃的这一方就会发出FIN,进一步触发四次挥手,此时连接就正常释放了,此时TCP的处理和进程会正常退出,和自动关闭没有区别
(2)主机关机
(正常步骤的关机)正常关机,就尝试先干掉所有的进程(强制终止进程)就和刚才所说的那个,崩溃的处理是一样的,主机关机会有一定时间,在这个时间之内,四次挥手可能正好挥手完毕
(3)主机掉电(直接拔电源没有任何反应时间)
此时没有任何的操作空间了,此时A无法给B发起任何的FIN的
这个时候分为两种情况
(a)如果B正在给A发信息(接收方掉电)
这个情况好办,B发的消息就没有ACK了,B就会触发超时重新传输,假如重传仍旧失败,就会触发复位报文(是RST为1)尝试重置连接,重置操作仍然是比啊,此时会单方面释放连接(B没有什么负面影响)
(b)如果此时A正在给B发送消息(发送方掉电了)
此时会更复杂一点,B在等A的消息,A突然不发了,B也不知道A是掉电了,还是等一会继续发,所以B会陷入阻塞等待,具体等多久,我们也不知道。
此处涉及到“心跳包”,B这边虽然是接收方,也会周期性给对方发起一个不携带任何业务数据(载荷)tcp接收包,发起这个包的目的,就是触发ACK,确认一下A是否正常工作/确认网路是否畅通。->A返回不了ACK,则A就挂了,和之前的流量控制,窗口探测是一个东西。
虽然TCP已经有心跳包支持了,但是还不够,往往还需要在应用层,应用程序中重新实现心跳包(TCP心跳包,周期太长,分钟级别是不够的,需要秒级或者毫秒级别的心跳包,可以更短时间内,发现某个服务器的问题。
(4)网线断开
以上TCP十大核心特性:
1.确认应答(可靠性)
2.超时连接(可靠性
3.连接管理(三次握手,四次挥手可靠性)
4.滑动窗口(效率)
5.流量控制(可靠性)
6.拥塞控制(可靠性)
7.延时应答(效率)
8.捎带应答(效率)
9.面向字节流->粘包问题(注意事项)
10.异常情况处理(心跳包->异常情况)