文章目录
- 一、滑动窗口
- 二、流量控制
- 三、拥塞控制
- 四、延时应答
- 五、捎带应答
- 六、面向字节流(了解)
- 七、异常情况(了解)
- 关于其他传输层协议
一、滑动窗口
为什么要引入滑动窗口?
确认应答和超时重传为TCP可靠传输机制提供支持。但同时也带来了效率上的折损。(Vudp>Vtcp)
为了减小速度降低的幅度,引入了滑动窗口机制。
什么是滑动窗口?
这其实是一个形象的比喻。原来我们的客户端/服务器收到数据就会立即尝试返回ACK,而当短时间内大量数据发送过来时,其他数据的发送就需要阻塞等待了。
而我们通过让多段的等待时间重叠在一起,一次发送多条数据,大大提高收发性能。其中这里等待时间重叠在一起的多段报文排列在一起,相当于有个隐形的框框,而这个框又动的所以我们把它称为滑动窗口。
这里的窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。
滑动窗口在这里具体怎么发挥作用的?
通过上边对定义的阐述,其实我们不难发现,这里效率的得以提高本质上其实是降低了确认应答等待ACK消耗的时间。(这里与IO那里其实是有点相似的)
我们假定这里的窗口大小是3,那么发送前3个段的时候,不需要等待任何的ack,直接发送;
收到第一个ack之后,窗口向后滑动,继续发送第四个段的数据。
【os内核为了维护这个滑动窗口,需要开辟发送缓冲区记录当前还有那些数据没有应答。只有确认应答的数据才可以从缓冲区删除,窗口越大,网络的吞吐量越大,传输效率越高,同时资源开销越多】
这个时候,我们再来想一个问题,数据报丢了怎么办?ack丢了怎么办
对于数据报丢了,会重传的,这里有种“快速重传”的机制。TCP有接收缓冲区的,会再接收缓冲区按照序号进行排队,所以顺序也不会乱。
对于ack丢了,其实这个时候我们可以通过收到的ack结果进行推断。
二、流量控制
什么是流量控制?
它是一种干预发送窗口大小的机制。
一般情况下(在cpu能处理的范围内),滑动窗口越大,传输效率越高。
接收方处理能力是一个很重要的约束依据,发送方发的速度,不能超出接收方的处理能力,需要协调发送方的发送速率。
为什么要引入流量控制?
- 完全不等ack,可靠性能否保障有待考量
- 窗口太大,也会消耗大量的系统资源
- 发送速度太快,接收方处理不过来,发了也白发。
怎么进行流量控制
核心就一句话:看接收方缓冲区的剩余大小。
接收方当前接收缓冲区的剩余空间大,就发的快些;小就发的慢些。
需要注意的点!!!!
- 这里其实就是协议端格式那里的16位窗口大小,但并不是简单的64Kb,TCP首部40字节选项中还有一个窗口扩大因子M,实际窗口大小是64kb左移M位得到的值。
- 窗口大小是发送方的概念,只不过这个值是需要ack返回的值计算赋给发送方的
- 发送方窗口大小不是固定值,而是随着传输过程动态变化的。当窗口大小变成0时,发送要终止。暂停发送,客户端会给服务器定时发送窗口探测报文。
三、拥塞控制
为什么要引入拥塞控制?
前边我们只是考虑了AB两个端点之间的通信,但实际上,中间还有很多节点(网络转发设备)。
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的 。
这里的拥塞控制就相当于交警一样,协调道路通畅。
什么是拥塞控制?拥塞控制具体是怎么发挥作用的?
这是一种大佬们想出的一种通过实验的方式,测得合适的传输速度。
它本质上是通过测试的方式,逐渐找到的一个合适的值。
注意!!!
- 窗口大小单位不是字节。具体大小视情况而定。
- 窗口大小不是固定数值,是随时间一直动态变化的。
- 拥塞控制和流量控制窗口共同决定了发送方实际的发送窗口(取较小值)
四、延时应答
为什么要引入延时应答?
为了进一步提高TCP的传输效率。
什么是延时应答?延时应答具体是怎么发挥作用的?
它也是提升效率的机制。当滑动窗口大一些,传输速度快一些,所以现在要做的就是在接收方能够处理的前提下,尽可能地把窗口变大。
收到数据之后,不是立即返回ack,而是稍微等一会再返回。等待的时间里,接收方的app能够把接收区缓冲区处理一部分。让接收区缓冲区尽可能的大一些。
而实际上,延时应答采取方式是,在滑动窗口下,ack不再每一条都返回,此时隔一条返回一个ack。
五、捎带应答
为什么要引入捎带应答?
也是为了提高TCP的传输效率。在延时应答的基础上,引入的捎带应答。
什么是捎带应答?
其实就相当于是一问一答。而服务器客户端最典型的模型就是一问一答。
六、面向字节流(了解)
面向字节流,虽然方便了传输,但是引进了麻烦事儿——“粘包问题”。
接收缓冲区,其实是把刚才这里收到的多个数据放到一起。应用read读取的时候,读到哪才算是一个完整的应用数据报。我们无从得知(由于TCP是字节流,一次读1个字节,读N个都可以。)
为此,我们可以采用应用层约定应用协议的方式,尤其明确好应用层数据报之间的边界。比如说约定好分隔符(必须是原来数据包里边没有的)、或者约定好每个包的长度,每次都按指定大小读取等。
七、异常情况(了解)
异常情况就是传输过程中出现了不可抗力,一般有一下几种情况。
- 进程崩溃
- 主机关机
- 主机断电
- 网线断开
12,来得及挥手,都相当于调用了close(方法,)进程无了、pcb无了、文件描述符表也没了。触发四次挥手,发送FIN。
这里的34,就来不及挥手了,认为连接还在,一旦接收端接收端认为连接还在,一旦接收端有写入操作,接收端发现连接已经不在了,就会进行reset。即使没有写入操作,TCP自己也内置了一个保活定时器,会定期询问对方是否还在。如果对方不在,也会把连接释放。
这里的掉电有两种情况:
- 接收方掉电:发送方拿不到ACK,之后进入超时重传,几次重传之后,触发RST复位报文段,之后放弃连接,对资源回收。
- 发送方掉电:此时,接收方还在尝试接收数据。这时,每隔一段时间,向对方发送一个PING包,期待对方返回一个PONG包,若没有返回,说明对方已经挂了,这就叫做采用保活机制(心跳包机制)。
关于其他传输层协议
传输层并不是只有TCP/UDP
针对不同的业务要求,会采取其他不同的传输层协议。
例如,对于游戏场景,就有一种比较典型的传输层协议——KCP。它的特点是即传输效率较高同时可靠性也是比较高。