【Java EE初阶十二】网络原理(二)

2. 传输层

2.2 TCP协议

2.2.2 关于可靠传输

4.滑动窗口

        前面的三个机制,都是在保证 tcp 的可靠性;

        TCP 的可靠传输,是会影响传输的效率的.(多出了一些等待 ack 的时间,单位时间内能传输的数据就少了);

        滑动窗口,就让可靠传输对性能的影响,更少一些.TCP 只要引入了可靠性,传输效率是不可能超过没有可靠性的 UDP 的,TCP 这里的"效率机制" 都是为了让可靠传输对传输效率的影响更小,尽可能的缩短和 UDP 的差距,即实际上缩短确认应答的的等待时间;

        正常的确认应答的简略图如下所示:

        针对上图由于收到确认应答的等待时间过长的修改措施是批量传输数振,如下图所示:

批量传输数振:
        不等 ack 回来,直接再发下一个数据;

        批量传输也不是无限传输的,批量传输也是存在一定的上限的.达到上限之后,再统一等待 ack;

        不等待的情况下,批量最多发多少数据,这个数据量,称为"窗口大小“;

        如上图所示,当前 A ->B 是批量的发了四份数据,此时 B 也要给 A 回应四组 ACK,但是当 A 已经达到窗口大小, 再收到 ACK 之前,不能继续往下发了.需要等待有 ACK 回来了之后,才能继续往下发.

        q1:这里的A是怎么继续发送消息的?是等待四个 ack 都回来了,在继续发四条?还是回来一个 ack 就继续发一个呢?

        a1:回来一个 ack, 就立即继续发一个;这里看起来的直观效果,这个"窗口"就开始往后"滑动",当然窗口越大, 等待的 ack 越多,此时传输效率也就越高.

        上述滑动窗口中,确认应答是可以正常工作的.但是如果出现丢包了咋办?
        我们当前这里的重传,相比于前面的超时重传,又有很多情况,如下所示:

情况一:ack 丢了

        当前这种情况, 不需要任何重传;所谓确认序号,表示的含义是,当前序号之前的数据,已经确认收到了.即下一个数据包你应该从确认序号这里,继续发送
        简单来说,如果 1001 这个 ack 丟了.但是 2001 ack到了.就可以说明2001 之前的数据都已经确认传输成功了,如此就涵盖了 1001 的情况!!!

情况二: 数据包丢了

        综上所述:主机 A 就需要知道是哪个数据丢了.主机 B 也就得告诉 A 是哪个数据丟了;

上述的重传过程中,并没有额外的冗余操作, 哪个数据丢了,就重传哪个,没丟的数据则不需要重传,总的来说就是整个过程都是比较快速的.(快速重传)

        如果通信双方,传输数据的量比较小,也不频繁,就仍然是普通的确认应答和普通的超时重传;
        如果通信双方,传输数据量更大,也比较频繁,就会进入到滑动窗口模式, 按照快速重传的方式处理;

        通过滑动窗口的方式传输数据,效率是会提升的.所谓窗口越大,传输效率就越大,(一份时间,等待 的 ack 更多了,总的等待时间更少了)
        但是滑动窗口, 设置的越大,不一定越好,如果传输的速度太快,就可能会使接收方,处理不过来了.此时,接收方也会出现丢包,发送方还得重传....由此会会造成tcp传输变得不太可靠起来;TCP 前提是可靠性,可靠性的基础上,再提高传输效率.

5、流量控制

        站在接收方的角度,反向制约发送方的传输速率.发送方发送数据报的速率,不应该超过接收方的处理能力,如下图所示:

        当数据到达B的系统内核中时,tcp socket对象上带有接收缓冲区,A ->B发的数据, 就会先到达 B 的接收缓冲区,8 这边还有应用程序,就会调用 read 这样的方法,把数据从接收缓冲区中读出来,进一步的进行处理.(一旦数据被 read 了,就可以从接收缓冲区中删除了),

        接收方每次收到数据之后,都会把接收缓冲区剩余空间大小,通过 ack 返回给发送方.发送方就会按照这个数值来调整下一轮的发送速度;

6、拥塞控制
        流量控制,是考虑的接收方的处理能力.
        拥塞控制则考虑的不仅仅是接收方,还有整个通信的路径.  拥塞控制则是考虑整个通信过程中间节点的情况(在中间的转发过程中,任何一个节点,处理能力达到上限,都可能会对发送方产生影响,都可能会影响到可靠传输)

        接收方的处理能力,很方便进行量化.但是由于中间节点,结构更复杂, 更难以直接的进行量化,因此就可以使用“实验”的方式,来找到个合适的值:

        首先让 A 先按照比较低的速度先发送数据(小的窗口),如果数据传输过程非常顺利,没有丢包,再尝试使用更大的窗口, 更高的速度进行发送,(一点一点变化);

        其次随着窗口大小不停的增大,达到一定程度,可能中间节点就会出现问题了.此时这个节点就可能会出现丢包,发送方发现丢包了,就把窗口大小调整小,此时如果发现还是继续丢包,继续缩小,如果不丢包了,就继续尝试变大;

        最后在这个过程中,发送方不停的调整窗口大小,逐渐达成"动态平衡“,这种做法就相当于把中间节点,都视为“整体”,通过试验的方式,来找到中间节点的瓶颈在哪里;

        关于拥塞控制的节点的相关图解如下图所示:

        流量控制和拥塞控制,都是在限制发送方的发送窗口的大小.最终时机发送的窗口大小,是取决于流量控制和拥塞控制中的窗口的较小值.

7、延时应答
        A 把数据传给 B,B 就会立即返回 ack 给 A[正常]
        也有的时候,A 传输给 B,此时 B等一会再返回 ack 给 A[延时应答] 

        延时应答的本质上也是为了提升传输效率,发送方的窗口大小, 就是传输效率的关键;流量控制这里,就是根据接收缓冲区的剩余空间来决定发送速率的。如果能够有办法,让这个流量控制得到的窗口更大点,发送速率就更快点(前提是能够让接收方还是能处理过来的)

        延时返回 ack,给接收方更多的时间,来读取接收缓冲区的数据,此时接收方读了这个数据之后,缓冲区剩余空间,变大了,同时返回的窗口大小也就更大

eg:

        初始情况下,接收缓冲区剩余空间是 10kb, 如果立即返回 ack,返回了 10kb 这么大的窗口.
如果延时个 200ms 再返回,这 200ms 的过程中,接收方的应用程序的,又读了 2kb,此时,返回的 ack, 就可以返回 12kb 的窗口了

8、捎带应答

        在延时应答的基础上,进一步的提高效率.网络通信中,往往是这种"一问一答”这样通信模型,即如下图所示:

        综上,本来是要传输两个 tcp 数据包 (封装分用两遍),目前通过上述操作,就可以把两个包合并成一个了.此时就可以得到更高效的效果,

9、面向字节流 

        这里有一个最重要的问题---->粘包问题 (不是 tcp 独有的,而是面向字节流的机制都有类似的情况)

        此处"包"应用层数据包.如果同时有多个应用层数据包被传输过去,此时就容易出现粘包问题,举个例子,如下图所示:

        目前,接收缓冲区中,这三个应用层数据包的数据,就是以字节的形式,紧紧挨在一起的,接收方的应用程序,读取数据的时候可以一次读一个字节,也可以读两个字节,也可以读多个字节;但是最终的目标是为了得到完整的应用层数据包,问题是B应用程序,就不知道缓冲区里的数据, 从哪里到哪里是一个完整的应用数据包了;

        相比之下,像 UDP 这样的面向数据报的通信方式,就没有上述问题,UDP 的接收缓冲区中,相当于是一个又一个的 DatagramPacket 对象,应用程序读的时候,就能明确知道哪里到哪里是一个完整的数据,如下图所示:

        q3:如何解决粘包问题?

        a3:核心思路: 通过定义好应用层协议,明确应用层数据包之间的边界,解决方法主要有下面两个:

        1、引入分隔符
        2、 引入长度.

        一个简单的例子,使用 \n 作为分隔符,如下图所示:

        引入例子,定义数据包的长度:

        需要注意的是,自定义应用层协议的格式,像xml,json,protobuffer等本身都是明确了包的边界的

10、异常情况的处理

        如果在使用 tcp 的过程中,出现意外,会如何处理?下面就针对一些出现的异常,就其相关的解决方案一一列列举:

1)、进程崩溃:

        进程没了,异常终止了.文件描述符表,也就释放了.相当于调用 socket.close(),此时就会触发 FIN,对方收到之后,自然就会返回 FIN 和 ACK,这边再进行 ACK (正常的四次挥手断开连接的流程),TCP 的连接,可以独立于进程存在(进程没了,TCP 连接不一定没;

2)、主机关机(正常流程)
        在进行关机的时候,就是会先触发强制终止进程操作,(相当于 1),此时就会触发 FIN,对方收到之后,自然就会返回 FIN 和 ACK;但是主机关机不仅仅是进程没了,整个系统也可能关闭了.如果在系统关闭之前,对端返回的 ACK 和 FIN 到了,此时系统还是可以返回 ACK,进行正常的四次挥手的,如果系统已经关闭了,ACK 和 FIN 迟到了,无法进行后续的ACK 的响应,站在对端的角度,对端以为是自己的 FIN 丢包了,重传 FIN.重传几次都没有响应,自然就会放弃连接.(把持有的对端的信息就删了)

3)、主机掉电 (非正常)

        此时,是一瞬间的事情,来不及杀进程,也来不及发送 FIN,主机直接就停机了.
        站在对端的角度,对端不一定知道这个事情咋搞,根据掉电的对端来分析:

        1、如果对端是在发送数据(接收方掉电),发送的数据就会一直等待 ack,触发超时重传,触发 TCP 连接重置功能,发起"复位报文段“,如下图所示:

如果 复位报文段发过去之后,也没有效果,此时就会释放连接了.

        2、如果对端是在接收数据(发送方掉电),对端还在等待数据到达.….等了半天没消息,此时其实无法区分,是对端没法发消息,还是对方挂了;TCP 中提供了心跳包机制.即接收方也会周期性的给发送方发起一个特殊的,不携带业务数据的数据包,并且期望对方返回一个应答
如果对方没有应答,并且重复了多次之后,仍然没有回复,就视为对方挂了,此时就可以单方面释放连接

4)、网线断开
        网线断开,和刚才的主机掉电非常类似的.

        当前假设,是 A 正在给 B发送数据,一旦网线断开,A 就相当于就会触发超时重传 ->连接重置 ->单方面释放连接;

        B 就会触发心跳包 ->发现对端没响应 ->单方面释放连接.

2.3 TCP和UDP之间的对比

        TCP 优势:可靠传输(TCP 适用于绝大部分场景.)
        UDP 优势:更高效率(UDP 更适合于, 对于"可拿性不敏感","性能敏感"场景)

"可拿性不敏感","性能敏感"场景--->局域网内部(同一个机房)的主机之间通信,即同一个机房内部, 网络结构简单,带宽充足,交换机/路由器网络设备负载程度也不是很高,出现丢包的概率就不大.故此往往也希望机器之间数据传输能更快.

        如果要传输比较大的数据包,TCP 更优先(UDP 有 64KB 的限制);

        如果要进行“广播传输”,优先考虑UDP,因为UDP天然支持广播,TCP不支持(所谓广播就是有一种特殊的场景,需要把数据发送给局域网的所有机器,这种情况就是广播);

ps:本篇的内容刀片这里就结束了,如果大家感兴趣的话就请一键三连哦!!!

        

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[嵌入式系统-24]:RT-Thread -11- 内核组件编程接口 - 网络组件 - TCP/UDP Socket编程

目录 一、RT-Thread网络组件 1.1 概述 1.2 RT-Thread支持的网络协议栈 1.3 RT-Thread如何选择不同的网络协议栈 二、Socket编程 2.1 概述 2.2 UDP socket编程 2.3 TCP socket编程 2.4 TCP socket收发数据 一、RT-Thread网络组件 1.1 概述 RT-Thread 是一个开源的嵌入…

【C Primer Plus第六版 学习笔记】 第十七章 高级数据表示

有基础&#xff0c;进阶用&#xff0c;个人查漏补缺 链表&#xff1a;假设要编写一个程序&#xff0c;让用户输入一年内看过的所有电影&#xff0c;要储存每部影片的片名和评级。 #include <stdio.h> #include <stdlib.h> /* 提供malloc()的原型 */ #include <s…

数据记笔记:USGS 查看上世纪卫星图

1 先到USGS EarthExplorer 界面&#xff0c;在address 处选择需要的城市/也可以在底下polygon处手动标出需要研究的区域 2&#xff0c;点击show&#xff0c;就会出找到的对应的区域&#xff0c;点击这个区域&#xff0c;polygon处就会有响应了。然后选择date range 3 点击下方的…

精工电联:定制精工线缆,赋能科技互联---致力于为客户提供卓越的连接线缆和连接器产品

精工电联 “定制精工线缆 &#xff0c;赋能科技互联”&#xff0c;精工电联致力于为高科技产业提供全方位、多维度的集成线缆解决方案。凭借深厚的研发实力和丰富的行业经验&#xff0c;精工电联已经成功地在工控设备、医疗设备、人工智能、新能源领域、轨道交通和超声波设备等…

7. Qt添加滑动条

前言&#xff1a; 添加一个这样的滑条&#xff0c;双方关联自动修改,也提供代码创建方式 技能&#xff1a; QSpinBox QSlider 方式一 Qt 的图形化编程&#xff08;用ui文件&#xff0c;非常简单&#xff09; 1.Spin Box 首先找到显示数字的这个部分。是input widget->sp…

Jenkins 2.426.3新版设置中文

1. 插件页面显示无法联网 &#xff0c;点击Plugins一直提示连接超时&#xff0c;设置公司代理后 2. 稍等一会儿点击如下图&#xff0c;插件就出来了&#xff0c;然后输入Locale进行下载 3. 以下是我下载安装好的 4.打开设置&#xff0c;找到Locale选项&#xff0c;设置成zh_CN…

相机图像质量研究(32)常见问题总结:图像处理对成像的影响--振铃效应

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

IDEA配置Lombok不起作用

IDEA配置Lombok不起作用 我们通常会只用lombok来简化代码。但是使用IDEA的lombok插件时&#xff0c;Lombok并不起作用。 可以按照如下操作。 FIle -> settings ->build,excecution,deployment–>compiler–>annotation processors勾选上 enable annotation proc…

Ubuntu 20.04 安装RVM

RVM是管理Ruby版本的工具,使用RVM可以在单机上方便地管理多个Ruby版本。 下载安装脚本 首先使下载安装脚本 wget https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer 如果出现了 Connection refused 的情况, 可以考虑执行以下命令修改dns,再执…

专业140+总410+合工大合肥工业大学833信号分析与处理综合考研经验电子信息与通信工程,真题,大纲,参考书。

经过一年努力奋战&#xff0c;今年初试总分410&#xff0c;其中专业课833信号分析与处理综合&#xff08;ss和dsp&#xff09;140&#xff08;感谢信息通信Jenny老师去年的悉心指导&#xff09;&#xff0c;数一130&#xff0c;顺利上岸&#xff0c;被合工大录取&#xff0c;看…

Open CASCADE学习|直纹曲面(ruled surface)

直纹曲面是一类特殊的曲面&#xff0c;在几何学和微分几何中都有研究。它的主要特性是&#xff0c;曲面上的每一点都有至少一条直线经过。换句话说&#xff0c;直纹曲面可以由一条直线通过连续运动构成。在三维欧几里德空间中&#xff0c;最常见的直纹曲面是平面、柱面和锥面&a…

【镜头知识】对焦和变焦

前言 变焦 调整某几个镜片的相对位置&#xff0c;从而改变镜片组的焦距&#xff0c;进而改变图像的视场角度。 焦距和视角以及拍摄距离的关系这张图能更好的体现&#xff1a; 视角越窄&#xff0c;也意味着放大的倍数越大&#xff01; 对焦 物体反射的光线&#xff0c;有很多不…