网络原理(4)——TCP协议的特性

目录

一、滑动窗口

1、ack丢了

2、数据丢了

二、流量控制(流控)

三、拥塞控制

拥塞窗口动态变化的规则

四、延时应答

五、捎带应答

六、面向字节流

七、异常情况

(1)进程崩溃了

(2)其中一方关机了(正常关机)

(3)其中一方断电了

1、接收方断电了

2、发送方断电了

(4)断网了(网线断开)


        以下是TCP协议传输数据过程中的一些特性

一、滑动窗口

        这里的滑动窗口和 oj题算法里的滑动窗口性质是一样的,不过这里的滑动窗口是为了提高网络传输信息的速度。

        如图,它是类似窗口这种,传输数据的时候是按窗口这种为单位进行传输的,这样传输的速度就会比一个一个数据的传要快。因为是花费一个传输数据的等待时间,但是能传输的数据是一个窗口这样单位的数据量。

        TCP这里反复强调数据传输是可靠的,那像上面这种以窗口为单位的方式传输数据,要是中间有丢包的情况,它又会怎么处理呢?

1、ack丢了

        如果是ack丢了,其实是没关系的,因为这里有确认序号,如果你接受到3001~4000,因为接受到后,确认序号就会变成4001,如果前面接受到1~3000的数据,然后接受方没有返回ack,但你此时的确认序号就是4001,那有关系吗,接受方已经知道了,而确认序号的4001就是表示4001前的数据它都收到了,下一个要接受的数据是4001。如图:

        

        如上图,虽然中间两个ack传输失败了,但这里的确认序号已经变成了4001,也就是说,4001之前的数据都收到了,接下来要收到的数据是4001了,也就是说,中间两次的ack发不发送给主机A都可以,因为我已经知道了4001之前的数据都收到了就像你在大街想加一个小姐姐的微信,结果人家小姐姐跟你说,人家都已经有娃了,那里面包含的信息不就是人家小姐姐已经谈过恋爱还结婚了。

2、数据丢了

        如图:

        如果1~1000的数据没有发送到主机B上,也就意味着主机B不会发送ack报文给主机A了,发送方在反复多次想主机A索要ack后还是收不到,发送方就会认为1~1000的数据丢包了,就会重传1~1000的数据给主机B。

        主机B因为拿不到1001之前的数据,就会反复想发送端索要;接下来就是重传3次后,主机B终于收到1~1000的数据了,主机B就会返回ack给发送方,然后主机B的确认序号就会变成4001,而不是1001;这是因为不管是发送方还是接收方,都会有接受缓冲区,前面1001~4000的数据主机B是收到了,但不会更新确认序号,而是把最新的确认序号放在主机B里的接收缓冲区中当拿到1~1000的数据后,就会返回ack给发送端,然后更新确认序号,这个新的确认序号就是在接收缓冲区中拿的。

        注意:这里的反复索要,次数也是有限的,如果反复多次索要合理的数据,还是不成功,想要的数据应该就是丢了,这里规定的次数也就相当于 “超时时间” 的判定了。

        上述的重传的过程,整体效率还是很高的,已经接收到的数据就不不必重传了,这里重传是针对没有接受到的数据(丢包了的)这里整体的效率没有损失,这种重传就称为快速重传

        这里的滑动窗口、快速重传、确认应答、超时重传是同时存在的,互不干扰如果滑动窗口的窗口比较小,也就是要传输的数据比较少,就会出现:滑不动的情况,这时为了保证可靠性,就会退化成确认应答,一个一个的数据进行传输,使用超时重传来保证其可靠性,此时判断是否丢包就是看是否到达时间还没返回ack如果数据很庞大,就会使用快速重传来保证其可靠性,此时判断是否丢包就是看是否有多个ack,索要同一个数据。


二、流量控制(流控)

        我们通过滑动窗口可以知道,这里的窗口越大,传输速度就会越快,但是窗口能无限大吗?答案显而易见:不能;以下是原因的解释。

        我们知道,发送方发送数据的速度是由滑动窗口的大小决定的,而接收方接受数据的速度是由它自身处理数据的能力决定的,如果发送方发送的数据太多、太快,接收方处理不过来这些数据了,第一时间这些处理不过来的数据会放在接收缓冲区里面,但如果缓冲区里面也满了,这时候,就会出现丢包。所以我们要控制窗口的大小,举个简单的例子,如图:

        我们想要让蓄水池不装满水的话,进水口的速度就要和出水口的速度持平,就算快一点点也没事,因为蓄水池有容量空间,可以储存在蓄水池里;但如果进水口速度过快,出水口就那么大点位置,不久后蓄水池就会装满水,这时候出水口排不出去这么多水,进水口那就会溢出浪费了。

        我们所说的流量控制也和上面的例子类似,要控制窗口大小,尽量让发送方的发送数据速度和接受速度持平,而为了让发送、接受速度尽可能持平,就要让接收方去影响发送方的速度,这就是流量控制。流量控制是通过下面这个字段反馈给发送方的:

        这个字段在普通报文段没有意义,在ack报文中才有意义也就是接收方接受到数据后,通过ack反馈给发送方,告诉发送方下次发送数据的速度(窗口大小)该如何调整而接收方通过自己的接受缓冲区剩余空间的大小,作为ack中窗口大小的数值,发送方接受到ack后,就会根据这个数值,来调整自己窗口的大小。大概流程如图:

        第一次传输1~1000的数据给主机B,主机B收到后根据自己接收缓冲区剩余大小,在ack中设置窗口大小报文,把ack返回给主机A,主机A就知道主机B的接收缓冲区还剩多少,从而调整主机A传输数据的窗口大小,把1001~4000数据批量的传输给主机B,此时主机B的接受缓冲区就满了,然后主机A这边等一定的时间,来接受主机B发送过来的窗口更新的通知,超过这个时间阈值还没等到主机B发来的通知,此时主机A就会发一个窗口探测包给主机B,索要窗口更新通知,等收到窗口更新通知后发现是2000,此时就主机A就发送4001~6000数据给主机B。

        这里16位窗口大小最大就是64k吗?其实不然,子啊TCP报头的选项中,还包含了一个参数:窗口拓展因子;而实际真实要设置的窗口大小是16位窗口大小 * 2^窗口扩展因子


三、拥塞控制

        拥塞控制和流量控制的本质都一样:限制发送方发送数据的速率。不过这里是站在有中间路径的角度看的

        我们知道,网络是非常复杂的,通过网络从A机器发送数据给B机器,中间要经过很多的路由器、交换机,其中这中间的设备情况都不一样,有些设备的负载不大,数据能正常传输,但有些设备可能负载很大,已经到它的极限了,这时候就会出现丢包的情况。如图:

        而拥塞控制就要考虑这种情况,然后调整发送方拥塞窗口的大小

        因为这里类似木桶效应,木桶能装多少水,取决于短板;上面的图也是类似的道理,有很多条路径传输数据的速度非常快,但有其中一个路径的设备高负载了,到极限了,只要数据经过这,就会阻塞,也就必须要调整发送方的窗口大小

        因为传输数据要经过中间路径,所以啥时候回堵塞,我们不能知道,是随机的这里为了调整窗口的大小,就只能 实验 了

        而窗口的调整也是动态变化的;因为我们无法控制啥时候传输数据的时候会堵塞,所以,只要丢包了,我们就认为数据在中间某个节点上阻塞了,从而缩小窗口大小,如果没丢包,就逐渐增大窗口大小;我们称为:动态变化。以下是动态变化的规则。

拥塞窗口动态变化的规则

        总的规则:流量控制和拥塞控制谁产生的窗口小,就是谁说的算。以下是拥塞控制产生的窗口大小规则:

        1、慢启动刚开始传输数据的时候,拥塞窗口会设置的非常小,传输的速率也就很小(如果一下子就把窗口设置太大,就可能导致设备的负载过高,从而在传输的过程中阻塞、丢包)。

        2、因为刚启动时的窗口非常小,此时为了提高传输效率,就会增大窗口,而这个窗口是随指数式增大的。

        3、随着窗口增大到一定程度,就不能继续让它指数式的增大了,因为指数式的增长的太快,窗口一下子增大的太大,就会导致网络拥堵、丢包这种情况;这里会设置一个 阈值 到达阈值后,窗口就会成线性式增大

        4、窗口是随着线性式的增大,也不能让它无限的增大如果增大到一定程度,出现了丢包的情况,就要让窗口大小重新回到一个比较小的值,然后回到慢启动这个过程并且这里会根据刚才丢包的窗口大小,重新设置限制指数增长的 阈值

        大概流程如图:

        如果出现丢包了,就要进入上面说的第四阶段,但这里有两个版本的慢启动一是旧版的,窗口大小回到非常小的值,经过指数增长再进入线性增长二是新版的,窗口不会回到非常小的值,也不会回到指数增长阶段,直接是线性增长阶段,指数增长阶段只会出现在刚开始的时候

        整个过程的窗口大小都是动态变化的,这个过程也非常像谈恋爱的过程


四、延时应答

        基于滑动窗口,来提高传输效率的延时应答就是发送方批量的发送数据给接收方,接收方收到这些数据,并不会一个一个ack的发送给发送方,而是等一段时间,等接收方处理一段时间刚发过来的数据后,才返回一个ack给发送方。为什么呢?

        原因就是接收方接收到数据,不是就直接处理这个数据的,而是先放到接收缓冲区中,然后再处理数据,如果等一段时间,接收缓冲区的数据就会变少,因为留有一定的时间把它们给处理了那返回ack中会带有窗口大小的报文,这个报文就是根据接收缓冲区的剩余空间来设置窗口大小的因为留有一段时间处理缓冲区的数据,所以接收缓冲区的剩余空间就变大了,窗口大小也会变大,传输数据的速度也会变快

        上面讨论过滑动窗口如果ack丢了的情况,这种情况没关系,因为有确认序号,所以丢了也没事;所以延时应答这里,就设置每处理几个数据,就返回一个ack回去,从而起到延时的效果,当然,这里等处理几个数据的时间也不是无限等的,而是会设置一个时间阈值,如果超过这个时间阈值,不管接收方还剩多少个数据没处理,都会返回ack

        所以延时应答的核心通过在允许的范围内(延时返回ack),增大滑动窗口的大小(提高数据的传输效率)。


五、捎带应答

        基于延时应答,用来提高数据传输效率的在数据传输中,如果发送方发送数据过来,我接收到了,然后因为延时应答,我可以等一段时间再返回ack回去,但因为有等待这一时间,就可以把ack连同响应,一起返回给发送方。大概流程如图:

        

        这里ack延时的这段时间结束后,服务器刚好把请求计算完,准备返回响应给客户端,这时候就可以把ack和response一起返回回去。当然,如果返回ack和发送请求的时机一样,也可以合并,就成了如图:

        因为延时应答,所以只要延时后ack返回的时机和发送数据的时机相同,触发了捎带应答,就可以把它们合并到一起进行发送。所以,基于延时应答+捎带应答,是可以把四次挥手变成3次的:fin fin+ack ack

        捎带应答啥时候触发,具体还得是看你代码具体咋写,下次发送过来的数据快不快,接受方处理数据的速度快不快


六、面向字节流

        这里核心要解决的问题:粘包问题

        因为TCP是传输数据的时候是以字节为单位进行传输的,那如果多次传输数据过去,这些数据就会在接收缓冲区中,因为全都是字节,在接收缓冲区中就无法辨哪到哪是一个完整的应用层数据包,这就是 粘包问题。如图:

其中解决粘包问题有两种方法

        (1)通过特殊符号作为分隔符例如上图说的用空白作为分隔符,如果遇到这个分隔符了,就说明一个包结束了。

        (2)指定包的长度会使用一个特殊的空间,表示一个数据包的长度,如图:

                

        对于 粘包问题,TCP协议是不会解决的要程序员自己编写代码解决这个问题,可以用上面这两种方法解决。

        而UDP协议就不会存在这种问题因为UDP协议面向的是数据报发送数据的单位是数据报,就能分隔开不同的数据内容;而UDP的接受缓冲区不是像上面这样的,而是类似数据结构中的链表,把每个的数据报给连接起来,如图:


七、异常情况

        异常的严重程度也是有高低之分的,一种是丢包了的异常,如果是丢包了,就直接触发TCP里的超时重传特性就好了;但也还有更严重的情况:网络故障,这该如何解决呢?

以下有不同网络故障的情况,其中也会介绍如何解决:

(1)进程崩溃了

        进程无论是正常关闭,还是异常崩溃,都会进行资源回收,也就是关闭文件的效果(系统内完成的),所以,如果是进程崩溃了,进程崩溃的一方肯定会执行到类似socket.close()的效果,也就是说一定能把 fin 给发送出去;而且 TCP连接 的生命周期比进程的生命周期长,这样也就能完成四次挥手的操作,把连接给断开了(双方把保存对端的信息给删除掉)。

(2)其中一方关机了(正常关机)

        当有个主机关机,就会强制杀死系统中所有的进程,进程关闭,也就一定会给对端发送 fin,对方接收到,也就会进行四次挥手的流程,但这里四次挥手不一定能挥完

        1、如果四次挥手挥的快,在系统关机前,把最后一个ack发送过去,就能完成四次挥手

        2、如果系统提前关机了,那也没事,至少把fin发送出去了,对端接收到 fin ,就会把ack和fin也返回回来,但是因为已经关机了,最后一个ack肯定不能给对端发送过去这时候对端很久都没有收到ack,就会触发超时重传,当重传几次后,还没有收到,对端就会单方面把连接给断开了,删除连接信息

(3)其中一方断电了

直接断电了,肯定就是来不及发送fin了,这里分为两种情况

1、接收方断电了

        发送方就会突然发现,ack没了,发送方就会尝试重传,重传几次后,发现还是没有ack返回回来,就会触发 “复位” 连接进行重连,要是重连不成功,发送方就会知道对方挂了,然后进行单方面的断开连接。复位连接需要用到RST复位报文段,如图:第四个

        复位连接:清除原来TCP的各种临时数据,重新开始连接,类似过去既往不咎的效果(此时的RST不会有ack的返回)。

剩下两个报文段:URG、PSH的简单介绍

        URG:与TCP带外数据有关系,TCP中有些特殊的数据包,携带一些特殊的功能。

        PSH:催促对方快点发消息给我。

2、发送方断电了

        接收方本身就是在阻塞等待对方发消息过来,如果迟迟没有信息回来,接收方就要试探一下,对方是不是挂了,这里就会使用 “心跳包” 来咨询对方情况心跳包也不带应用层的数据的,是一个特殊的数据包,带有周期性的发送给对端,这个周期、频率程序员是可以自己设置的当发送心跳包后, 没有返回 “心跳” ,就视为对方挂了;如果对端挂了,也就会进行单方面的断开连接。

(4)断网了(网线断开)

        结合接收方和发送方都断电的情况


都看到这了,点个赞再走吧,谢谢谢谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/481611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

虚拟机开机启动失败,进入(initramfs)解决办法

虚拟机开机启动失败,进入(initramfs)解决办法 打开虚拟机中Ubuntu时进入(initramfs),导致无法进入桌面。问题如下图显示: 命令行输入 fsck -y /dev/sda5输入 exit进入 选择root 后回车 输入虚拟机的密码 进入 root …

网络原理(5)——IP协议(网络层)

目录 一、IP协议报头介绍 1、4位版本 2、4位首部长度 3、8位服务器类型 4、16位总长度 5、16位标识位 6、3位标志位 7、13位偏移量 8、8位生存空间 9、8位协议 10、16位首部检验和 11、32位源IP地址 12、32位目的IP地址 二、IP协议如何管理地址? 1、动…

《剑指 Offer》专项突破版 - 面试题 88 : 动态规划的基础知识(C++ 实现)

目录 前言 面试题 88 : 爬楼梯的最少成本 一、分析确定状态转移方程 二、递归代码 三、使用缓存的递归代码 四、空间复杂度为 O(n) 的迭代代码 五、空间复杂度为 O(1) 的迭代代码 前言 动态规划是目前算法面试中的热门话题,应聘者经常在各大公司的面试中遇到…

STM32 CAN的工作模式

STM32 CAN的工作模式 正常模式 正常模式下就是一个正常的CAN节点,可以向总线发送数据和接收数据。 静默模式 静默模式下,它自己的输出端的逻辑0数据会直接传输到它自己的输入端,逻辑1可以被发送到总线,所以它不能向总线发送显性…

STM32利用串口标准库发送字节,发送数组,发送字符串,发送数字,实现printf功能。

早晨到现在刚刚完成的功能:发送字节,发送数组,发送字符串,发送数字,实现printf功能。 当然这是建立在昨天学习使用串口发送数据的基础上,新建立的功能函数,咱们先来看看这次实验的结果吧&#…

CCDP.02.OS正确部署后的Dashboard摘图说明

前言 在部署成功OpenStack后,应该可以在浏览器打开Dashboard,并对计算资源(这里主要是指VM)进行管理,也可以在Dashboard上面查看OpenStack是否存在错误,下面,已针对检查的关键点,用红…

程序员表白

啥?!你说程序员老实,认真工作,根本不会什么表白!那你就错了!(除了我) 那今天我们就来讲一下这几个代码!赶紧复制下来,这些代码肯定有你有用的时候! 1.Python爱心代码 im…

IAB欧洲发布首张泛欧洲数字零售媒体能力矩阵图

2024年1月18日,互动广告署-欧洲办事处(IAB Europe)发布了首张泛欧洲数字零售媒体能力矩阵图。为媒体买家提供的新资源概述了在欧洲运营的零售商提供的现场、场外和数字店内零售媒体广告机会。 2024年1月18日,比利时布鲁塞尔,欧洲领…

算法系列--递归(2)

💕"什么样的灵魂就要什么样的养料,越悲怆的时候我越想嬉皮。"💕 作者:Mylvzi 文章主要内容:算法系列–递归(2) 前言:今天带来的是算法系列--递归(2)的讲解,包含六个和二叉树相关的题目哦 1.计算布尔⼆叉树的…

企业微信可以更换公司主体吗?

企业微信变更主体有什么作用?当我们的企业因为各种原因需要注销或已经注销,或者运营变更等情况,企业微信无法继续使用原主体继续使用时,可以申请企业主体变更,变更为新的主体。企业微信变更主体的条件有哪些&#xff1…

Ambari+Metrics+Bigtop 全家桶编译部署攻略——Ambari系列

您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 写在前面: 1、源码已经完成Ambari+Metrics+Bigtop 最新版的编译及部署,后续会放魔改包和一件部署脚本 2、时间有限,我会尽快更新完毕所有内容…

python 空间距离计算

目录 python 空间距离计算 已知两点,画三角形 批量矩阵计算 python 空间距离计算 要在空间中找到一个点,使其位于点 b 和 c 之间的连线上,并且与点 b 的距离等于点 a 到点 b 的距离的2倍。 import numpy as npif __name__ __main__:a …

【机器学习入门 】逻辑斯蒂回归和分类

系列文章目录 第1章 专家系统 第2章 决策树 第3章 神经元和感知机 识别手写数字——感知机 第4章 线性回归 文章目录 系列文章目录前言一、分类问题的数学形式二、最大似然估计三、交叉熵损失函数四、多类别分类多类别逻辑斯蒂回归归一化指数函数交叉熵误差和均方误差的比较 五…

docker (一)

1,什么是docker 首先我们可以好好的看看docker的那个可能的图标,你想象到了什么? ... docker是一个开源的应用容器引擎,有Docker公司(前dotCloud公司)开发,基于Apache2.0开源授权协议发行。该…

网络工程师笔记15(OSPF协议-2)

OSPF协议 OSPF是典型的链路状态路由协议,是目前业内使用非常广泛的 IGP 协议之一。 Router-ID(Router ldentifier,路由器标识符),用于在一个 OSPF 域中唯一地标识一台路由器。Router-ID 的设定可以通过手工配置的方式,或使用系统自…

吴恩达机器学习笔记 二十七 决策树中连续值特征的选择 回归树

还是猫狗分类的案例&#xff0c;假如再增加一个特征weight&#xff0c;该值是一个连续的值&#xff0c;如何在决策树中使用该特征&#xff1f; 如下图所示&#xff0c;尝试不同的阈值&#xff0c;如 weight<9 , 此时左边有四个样本&#xff0c;都为猫&#xff0c;右边有六个…

c语言--内存函数的使用(memcpy、memcmp、memset、memmove)

目录 一、memcpy()1.1声明1.2参数1.3返回值1.4memcpy的使用1.5memcpy模拟使用1.6注意 二、memmove()2.1声明2.2参数2.3返回值2.4使用2.5memmove&#xff08;&#xff09;模拟实现 三、memset3.1声明3.2参数3.3返回值3.4使用 四、memcmp()4.1声明4.2参数4.3返回值4.4使用 五、注…

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities)下

Android视角看鸿蒙第八课(module.json5中的各字段含义之abilities&#xff09;下 导读 上篇文章开始学习abilities下的各字段含义&#xff0c;因为篇幅原因只学习了name、srcEntry、description、icon和label字段的含义和用法&#xff0c; 这篇文章继续学习和了解其他字段。 …

二叉树|106.从中序与后序遍历序列构造二叉树

力扣题目链接 class Solution { private:TreeNode* traversal (vector<int>& inorder, vector<int>& postorder) {if (postorder.size() 0) return NULL;// 后序遍历数组最后一个元素&#xff0c;就是当前的中间节点int rootValue postorder[postorder.…