0
点赞
收藏
分享

微信扫一扫

Tcp协议的相关特性

萨科潘 2022-04-18 阅读 53
java网络

目录

1)确认应答

2)超时重传

3)连接管理机制

4)滑动窗口

 5)流量控制(是滑动窗口的延伸,目的是为了保证可靠性)

6)拥塞控制(也是滑动窗口的延伸,也就是限制滑动窗口发送的速率)

 7)延时应答(相当于流量控制的延伸)

8)捎带应答

9)面向字节流  -->粘包问题

10)TCP异常情况

如何基于UDP协议实现可靠传输?

啥样的场景中适合使用TCP,啥用的场景中适合使用UDP?


1)确认应答

可靠性:简单来说就是发送方发出去数据之后,能够知道对方有没有收到~~

保证可靠传输的核心机制,关键就是接受方收到消息之后,给发送方,返回一个应答报文(ACK),表示自己已经收到了

举个例子说明:

如果数据就是按照这样的方式传递没有什么问题,但如果收到的消息先是“滚”,其次才是“好呀好呀”,这是就会出现“误会”

之所以会出现这种问题,是因为网络上,数据接收的顺序,不一定和发送的顺序完全一致!!,存在后发先到的情况,因此这时我们只要对消息进行编码就可以解决,如下:

Tcp的针对消息的序号,并不是按照“消息条数”来进行编号的,而是按照字节来编号

2)超时重传

相当于对确认应答进行了补充,确认应答是网络一切正常的时候,通过ACK通知发送方我收到了,如果出现了丢包的情况,超时重传机制就起到了效果

出现丢包的两种情况:

(1)发出去的消息丢了

         当我发出消息后,就担心这个消息是不是丢了,我就在等这个ACK,如果确实发丢了,对方直接就没有接收到,我这里肯定就没法收到ACK

        此时超时重传就起到了作用,因为我没有收到ACK,我就认为我的消息可能发丢了,那么就会再一次发送

(2)另一种情况就是ACK丢了,虽然对方收到了,但是我没有收到ACK

      由于我没法区分到底是因为那种原因导致的没有收到ACK,所以就认为对方压根没有收到,再重新发送一次,这里的重发不是立即发送,而是等待一会再重发

如果是第二种原因,那么对方会不会收到重复消息?当然不会。

因为:Tcp内部有一个去重操作

           接受方收到的数据会先放到操作系统内核的“接收缓冲区”中

           接收缓冲区可以视为是一个内存空间,并也可以视为一个“阻塞队列”

收到的数据Tcp会根据序号,来检查数据是否在缓冲区中,如果存在就直接丢弃,不存在就放进去,从而保证程序调用socket  api拿到的数据是不重复的

注意:重传如果失败,可能还会继续尝试,但也不会无休止尝试....

基于上述两种机制,TCP的可靠性就得了保证

3)连接管理机制

点击以下链接查看

https://blog.csdn.net/qq_64421953/article/details/124156951?spm=1001.2014.3001.5502

4)滑动窗口

滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高传输效率

滑动窗口的本质就是在“批量的发送数据”,一次发一波数据,然后一起等一波ACK

由于确认应答机制的存在,导致了当前每次执行一次发送操作,都需要等待上一个ACK的到达,大量时间都浪费在了等ACK中

如果一次批量发送的数据为N,此时这里N称为“窗口大小”

“滑动”的意思是,并不用把N组数据ACK都等到了,才继续往下发送,而是收到一个ACK,就继续往下发送一组

当前这个窗口大小越大,可以认为就是传输速度越快~~

批量发送的情况下,容易出现两种“丢包”的情况

(1)ACK丢了(这种情况不用处理,只要你最后一条数据收到,就能自动涵盖了之前的数据)

(2)数据丢了

由于1001--2000这个数据丢了,所以B就再反复索要1001这个数据,及时A给B已经往后发了,这个时候仍然是在索要1001~~

当索要若干次之后,A就明白了,就会触发重传

这里重传只需要把丢失的那一块数据给重传了即可,其他已经到了的数据就不必在重传了,整体的重传的数据还是挺高的

 5)流量控制(是滑动窗口的延伸,目的是为了保证可靠性)

在滑动窗口中,窗口越大,传输速率越高,不光要考虑发送发,还要考虑接收方

假如发送方发的很快,接收方根本处理不过来,接收方就会把新收到的包给丢了,发送方就得重传

流量控制的关键:就是得能衡量接收方的处理速度

这里直接使用接收方接收缓冲区的剩余大小,来衡量当前的处理能力

接收缓冲区就是在发送方与接收方之间会有一个“交易场所”,简称“接收缓冲区”,发送方发送的数据线=先放到“交易场所”,由于“接收缓冲区有一个总大小”,随着数据的放入,剩余空间就会逐渐变小

如果剩余空间比较大,就认为接收方的处理能力比较强,就可以让发送方发的快一些

如果剩余空间比较小,就认为接收方的处理能力比较弱,就可以让发送方发的慢一点

至于如何知道剩余空间大小?

是通过ACK报文来告知
在这里插入图片描述

那是不是当窗口大小为0时,是否意味着发送方就不会发送数据了呢?

虽然接收方反馈的窗口大小是0,但是发送方也不能完全不发送数据,而是需要定期发送一个探测报文,探测报文不传输实际的数据,只是为了触发ACK,从而为了知道当前窗口大小是多少~~

6)拥塞控制(也是滑动窗口的延伸,也就是限制滑动窗口发送的速率)

拥塞控制衡量的是,发送方到接收方,这整个链路之间,拥堵情况的处理能力

 

正如A能够发多快,不光取决于B的处理能力,也取决于中间链路的处理能力

拥塞控制的处理方案,就是通过“实验的”方式,逐渐调整发送速度,从而找到一个一个比较合适的范围 ——拥塞窗口就在这个范围中不断变化,从而达到“动态平衡”

具体这个拥塞窗口是如何变化的呢?

(通过这个拥塞窗口来制约滑动窗口的大小)

 A:属于最开始的时候,取得初始窗口大小非常小

A--B:初始情况下给的窗口大小太小了,可能适合更大的值,所以程指数规律增长

B:B也称为阈值,到达B值后,也就决定了啥时候从“指数->线性”,这个阈值也不是一直不变的,当每次出现丢包后,阈值就会更新为出现丢包窗口的一半(比如D)

B--C:指数增长一定程度后,就会进入线性增长

C:当线性增长到一定程度后,就会出现丢包,一旦丢包,此时发送方就会立即让窗口变小(然后继续重复刚才的指数增长+线性增长过程,不过这次阈值就会变成“D”点)

 7)延时应答(相当于流量控制的延伸)

简单来说:流量控制就是踩了刹车,使发送方,发的不要太快

                   延时应道,就想在这个基础上,能够尽量再让窗口更大一些

 比如一边进水一边出水

,采取的措施就是不立即回答剩余多少,而是迟一些回答,在这期间,又往里注入了一点水,这个操作就是在有限的情况下,又尽可能的提高了一点传输速度

8)捎带应答

在延迟应答的基础上, 我们发现, 很多情况下, 客户端服务器在应用层也是 “一发一收” 的. 意味着客户端给 服务器说了 “How are you”, 服务器也会给客户端回一个 “Fine, thank you”

那么这个时候ACK就可以搭顺风车 , 和服务器回应的 “Fine, thank you” 一起回给客户端

客户端与服务器之间的通信,有以下几种模型:

(1)一问一答:客户端发送一个请求,服务器返回一个对应的响应

(2)多问一答:上传文件

(3)一问多答:下载文件

(4)多问多答:直播~,串流~

9)面向字节流  -->粘包问题

TCP粘包指的是粘的是应用层数据报,在TCP接受缓冲区中,若干个应用层数据包混在一起了,分不出谁是谁了

在TCP的协议中,没有如同UDP一样的“报文长度”这样的字段,但有一个序号这样的字段

站在传输层的角度,TCP是一个一个报文过来的,按照序号排好放在缓冲区中

站在应用层的角度,看到的是一串连续的字节数据

那么应用程序看到了这么一连串的字节数据,就不知道从那个部分开始到哪个部分,是一个完整的应用层数据包

注意:粘包问题不是TCP独有的问题,只要是“面向字节流”都会涉及到粘包,面向数据报的UDP就没有这个问题

10)TCP异常情况

(1)进程终止

在进程毫无防备的情况下,偷袭他,突然结束进程。

TCP连接,是通过socket来建立的,socket本质上是进程打开的一个文件,文件其实就存在于进程的PCB里面有个文件描述符表;每次打开一个文件,都在文件描述符表里,增加一项;每次关闭一个文件,都在文件描述符表里进行删除一项

如果直接杀死进程,PCB也就没了,里面的文件描述符表也就没了此处的文件就相当于‘自动关闭’了,这个过程其实和手动调用socket.close()一样,都会触发4次挥手

(2)机器关机

按照操作系统约定的正常流程关机

正常流程的关机,会让操作系统,杀死所有的进程,然后关机

(3)机器掉电/网线断开

台式机直接拔电源,系统不会有任何反应时间,更不会有任何的处理措施

如果B断电,意味着A发送的数据不再有ACK了,A就会进入超时重传逻辑;重传几次之后,A认为这个连接已经出现严重故障了;尝试重新建立连接,连接失败之后,就会放弃连接

如果A断电,B就不知道当前是A挂了,还是A休息会再继续,B就会时不时的给A发送一个小报文(不带有实际数据,只是为了触发ACK),通过探测报文,发现A不再返回ACK,因此B就认为A出现了问题

如何基于UDP协议实现可靠传输?

这个问题其实就是考TCP,本质上就是在应用层基于UDP复刻TCP的机制

实现确认应答机制,每个数据收到之后,都要反馈一个ACK

实现序号/确认序号,以及实现去重

实现超时重传

实现连接管理

要想提高效率,实现滑动窗口

为了限制滑动窗口,实现流量控制/拥塞控制

实现延时应答,捎带应答,心跳机制...

啥样的场景中适合使用TCP,啥用的场景中适合使用UDP?

(1)对可靠性有一定要求的时候,使用TCP(日常开发中的大多数情况,都基于TCP)

(2)如果传输的单个数据报比较长(超过64k),首选TCP

(3)啥时候使用UDP?对可靠性要求不高,对于效率的要求更高 

举报

相关推荐

0 条评论