TCP协议的可靠性详解

        由于网络部分内容相对于来说比较多,本文只针对TCP协议来进行讲解,后面UDP/Http/Https的讲解有可能会单独出一篇文章。 udp协议相对来来说会比tcp简单不少,同时面试频率tcp也会高上不少。
        同时本博客也仅仅只是做出部分讲解,并不适合系统全面的学习,要想真系统且全面学习的话,本人推荐去百度找------RFC标准文档 (百度RFC tcp)应该就可以出来

TCP协议特点

TCP协议的格式,下面的内容会对上述部分内容做详细讲解。

1. 确认应答

       tcp的可靠传输机制主要是靠确认应答机制来实现的。确认应答就是每一次客户端向服务器发送请求之后,服务器都会返回一个请求到客户端,表示我收到了你发送过来的请求。

就比如,当我去找我女神的时候,我在手机上向我女神发送了一个消息,说我想和她出来一起吃饭,然后女神通过手机回复我了一条短信就说,可以哇。就表示了一次通信,我像女神发的消息就表示了一条请求,女神的这次回复就是确认应答机制。 这样我就知道我女神是否愿意出来吃饭了。

但是其实确认应答机制只看上述条件的话,其实是存在一个弊端的。 还是同样的场景,我向我女神发送了2条消息

  1. 女神,节日快乐给你发个520红包哇
  2. 女神,我喜欢你,做我对象好不好哇

此时我按上述顺序给我女神发了2条信息,我女神收到后针对上述2条信息给了我2条回复

  1. 可以啊 
  2. 滚啊

不能看出此时的女神对我的红包还是有意思的,但是对我意思可能不怎么大,但是在网络通信传输的过程中,要是出现了一点意外导致2那条消息先传给我了,1那条消息后面才传过来,此时对我来说,我就很可能会理解为 我女神不接受我的红包,但是接收了我的表白(不愧是我看上的女神) 。但女神的本意并不是如此,所以传输和接收的顺序也尤为重要。 每条信息在通信过程中,所走的路线和节点并不相同,同时速度也和各个节点的硬件和其他很多物理因素所影响,所以后发先到,其实也是很常见的事情,但是后发先到会引起比如上述这样很麻烦的事。

tcp在解决上述问题中采用了一种很简单的方式,通过给每一条数据进行编号。就是在上述我向女神发送消息的前面加上编号,第一条就编号一,第二条就编号二,同时在我返回的数据中也带上编号,第一条就是编号一 第二条就是编号二,这样我就知道原来我女神是拒绝了我这样的现实了。但是在TCP中编号其实是蛮复杂的。

因为tcp协议是面向字节流的,不是一条一条传输的。所以在tcp实际编号的过程中,是按照字节来进行的编号。

在上图中 第一条数据是1000的大小,第二条也是1000的大小,但是在实际过程中,可以不用向上述那样发请求第一条可以使1-888 第二条889-1000也是可以的,这里的大小是自己定的。但是为了方面我们后面的内容就按照上述图片进行一个讲解。

上述图片中 在收到了第一条请求(1  -  1000)之后,返回了一个数据1001,这个1001表示的含义是表示1001编号以前的数据我都接收到了,下一次发送你应该从1001开始发送,并不是返回数据最后的下一位。
所以不难看出,tcp协议只需要在报头中将第一个数据的编号表示出来,然后结合报文长度,就可以知道当前tcp编号大小了

里面的32位序号所对应的就是报文第一个字节的编号。(超出了之后就重头开始计算不怎么影响,因为4个字节32比特位可以表示4gb的数据 所以一般不会超,超了也没事)

里面的32位确认序号就是专门给应答报文使用的。

所以为了区分这是普通报文还是应答报文,在tcp协议中还引入了标志位,要是其中ACK(第二位)(acknowledge)为0表示当前为无效位,表示当前是一个普通报文,1表示有效,表示当前是一个应答报文。同时应答报文也会携带一个32位序号,但这个32位序号和正常报文的序号是没有关系的,序号是针对于某一个主机发送的内容进行编号。

所以在上述内容中铺垫了这么多,核心一点就是 确保可靠性的核心机制是确认应答

2. 超时重传

但是上述情况都是一种很理想的情况,这里我们讨论一种常见的情况,就是存在丢包的情况。在一般我们信息和数据传输的过程中,数据是由一个一个的交互机/路由器进行传输的,要是数据量少,机器的负载可能相对较小,但是对于数据量大一点的场景,机器压力一点过大,机器开始摆烂了,就可能会造成数据丢失的情况,也就是丢包。

但是要是真的出现丢包了,比如我给我女神发送了一条信息(理想状态的女神就是每一条信息都会回复的那种),但是我女神没有收到,就没有给我回复,难到我就放弃了嘛。肯定不是哇。这时候我会先等一等,确认我女神是没有收到消息之后,我会尝试在发送一次。直到我女神收到了我发送的信息。

上述过程也就是TCP中的超时重传机制,就是我设置一个等待时间,要是时间到了我还没有收到确认应答,我就重新发送报文。

所以超时重传的前提是丢包,这里不难理解吧。此时,我们又需要进行分类讨论了

  • 发送消息的包丢失
  • 确认应答的包丢失

丢包的过程中,上述2中包都存在丢失的可能。 但其实站在发送方的视角来看,他并不知道是那种丢包的情况呀。 所以既然反正都区分不了,那我直接摆了,都进行超时重传。但是,都进行超时重传的话,站在第一种情况来讲,没啥大问题,但是要是站在下面那种情况来讲的话,就有问题了,要是确认应答的报文丢失,但我还去重传一个,那服务端此时不就收到2份数据了嘛。要是在平时的充值过程中,我充了6元钱他直接给我扣了12,就会引发我很大的经济危机。

所以在客户端接收数据的过程中其实是会进行一个去重操作的。

这里tcp协议可以直接使用序列号进行一个去重,tcp会在内核中给每一个socket对象安排一个内存空间,就等于一个队列类似的数据结构,也被称为“ 接收缓冲区 ”收到的数据都会放进去,并且排好顺序,所以可以很容易的判断当前数据是否重复了。同时使用一个数据就在队列中进行删除。

有人可能会想到,要是这个数据已经被删除了,但是以前超时重传发送的一条数据又来了,这样会重复发起请求吗。其实在上述确认序号中已经解决这个问题了,因为队列中的数据是按顺序排列的,同时要是新来的请求序号小于已经返回的序号,则可以直接判断为已经接收过的数据了。

同时,队列中的数据有序排列,其实也很好的解决了上述的后发先到问题。在数据到达之后会进行一个重新排序的过程。

我们假设我们服务器丢包率为2%(已经很高很高了)在超时重传的过程中第一次丢包的过程是2%要是触发了超时重传第二次传递还是丢包的概率为2%*2%了 已经很小了,所以随着次数的增加,传输成功率是会增大的,但是也存在因为一定的原因,一直丢包,此时,要是一直丢包,每一次超时重传的等待时间会越来越长,直到一定次数之后,就放弃重传了。此时就会尝试重置TCP的连接。此时客户端就会发起一个复位报文 

也就是上图的RST会表示为1,也就是复位报文,就表示希望重置连接。但是丢包率这么严重的情况下,一般复位报文也不会收到回应了,此时客户端就会删除对端信息,放弃连接。

所以超时重传也是对TCP机制可靠性的一个重要补充。 

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

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

相关文章

代码随想录算法训练营Day11 | 20.有效的括号、1047.删除字符串中的所有相邻重复项、150.逆波兰表达式求值

20.有效的括号 题目:给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右…

B站美化插件,支持自定义,太酷辣~

大公司的软件和网站通常具有优雅的默认界面设计。 以国内二次元聚集地B站为例,可以说它的UI设计非常吸引人。与其他视频网站繁复的设计相比,B站的界面设计可以说是遥遥领先 然而,总有些人对默认的用户界面感到不满意,他们渴望尝试…

数字逻辑电路基础-有限状态机

文章目录 一、有限状态机基本结构二、verilog写一个基础有限状态机(moore型状态机)三、完整代码一、有限状态机基本结构 本文主要介绍使用verilog编写有限状态机FSM(finite state machine),它主要由三部分组成,下一状态逻辑电路,当前状态时序逻辑电路和输出逻辑电路。 有…

Spring Security认证流程分析

我自己的思路 先分别实现 userdetailsService,userDetails,passwordEncoder三个接口, 然后就是写登录逻辑 本文章用的是继承UsernamePasswordAuthenticationFilter这个接口 因为这个框架默认登录逻辑是在这里面的,里面的核心就是…

【Vue3+Tres 三维开发】01-HelloWord

预览 什么是TRESJS 简单的说,就是基于THREEJS封装的能在vue3中使用的一个组件,可以像使用组件的方式去创建场景和模型。优势就是可以快速创建场景和要素的添加,并且能很明确知道创景中的要素构成和结构。 项目创建 npx create-vite@latest # 选择 vue typescript安装依赖…

广西民族师范学院领导一行莅临泰迪智能科技开展“访企拓岗”活动

4月25日,广西民族师范学院数理与电子信息工程学院党委副书记、纪委书记主战河,数理与电子信息工程学院副院长陆克盛、专任教师韦吉栋、黎运宇、黄恒秋、王贵富莅临广东泰迪智能科技股份有限公司就深入实施“访企拓岗”、强化校企合作、促进毕业生充分就业…

搞定Microchip MPU的U-boot源码仿真调试

文章目录 准备工作编译at91bootstrap和U-boot源码下载并编译at91bootstrap源码下载并编译u-boot源码 使用Eclipse导入U-boot源码并进行配置cfg配置文件内容仿真调试视频教程 在嵌入式Linux开发中,免不了接触到U-boot,随着U-boot功能越来越强大&#xff0…

2024年4月26日力扣每日一题(1146)

2024年4月26日力扣每日一题(1146) 前言 ​ 这道题在做的时候感觉很简单,题意很容易理解,但直接去做直接干爆内存,参考了一下灵神的代码,豁然开朗,觉得这道题很有意思,便想着写篇博…

【YOLO改进】换遍IoU损失函数之GIoU Loss(基于MMYOLO)

GIoU损失函数 论文链接:https://arxiv.org/pdf/1902.09630 GIoU(Generalized Intersection over Union)损失函数是一种用于改善目标检测模型中边界框回归的方法。它是基于传统的IoU(交并比)损失的一个改进版本,解决了…

node.js的安装与配置

Node.js 是一种基于 JavaScript 编程语言的服务器端平台,它可以让你在浏览器之外运行 JavaScript 代码。以下是 Node.js 的安装步骤: 下载 Node.js: 访问 Node.js官网。根据你的操作系统选择合适的版本下载。 运行安装文件: 在下载…

计算机视觉——使用OpenCV GrabCut算法从图像中移除背景

GrabCut算法 GrabCut算法是一种用于图像前景提取的技术,由Carsten Rother、Vladimir Kolmogorov和Andrew Blake三位来自英国剑桥微软研究院的研究人员共同开发。该技术的核心目标是在用户进行最少交互操作的情况下,自动从图像中分割出前景对象。 在Gra…

直流有刷电机入门

文章目录 123455.25.3 1 2 电刷 材质是 石墨 3 130马达 就几毛钱 几块钱这学的就是减速电机P MAX一定 pf*v 降低速度 扭矩就会大 4 还有空载电流 过大负载 时 有堵转电流 (可分析电流 来看电机工作状态)RPM 转每分钟 5 5.2 这的线圈 是简化后的转子绕组…

Ubuntu终端常用指令

cat cat 读取文件的内容 1、ls 一、 1、ll 显示当前目录下文件的详细信息,包括读写权限,文件大小,文件生成日期等(若想按照更改的时间先后排序,则需加-t参数,按时间降序(最新修改的时间排在最前)执行: $ ll -t, 按时间升序执行: $ ll -t | tac): ll 2、查看当前所处路径(完整…

服务器数据恢复—服务器重装系统导致XFS分区丢失的数据恢复案例

服务器数据恢复环境: 一台服务器MD1200磁盘柜,通过raid卡将15块磁盘组建成一组raid5磁盘阵列。raid5阵列分配了2个lun,操作系统层面对lun进行分区:1个分区采用LVM扩容方式加入到了root_lv中,其余分区格式化为XFS文件系…

大数据时代,保护个人隐私小Tips Get 起来!

随着大数据时代的到来,我们的隐私正处于越来越易被侵犯的风险中。在各种社交媒体和信息共享平台上,我们需要输入各种个人信息,而这些信息可能被不法分子盗取,甚至被用来进行欺诈行为。在如今的大数据时代,保护个人隐私…

元宇宙中的DAPP:你了解多少?

元宇宙是什么?这是一个在当今科技圈炙手可热的话题。而在元宇宙中,DAPP起着至关重要的角色,它作为连接现实世界与虚拟世界的桥梁,为未来的数字世界开启了一个全新的篇章。 一、元宇宙:一个虚拟的数字世界 元宇宙是一…

【JavaWeb】Day51.Mybatis动态SQL(一)

什么是动态SQL 在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。 而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面只传递了参数姓名name 字…

【麒麟(Linux)系统远程连接到windows系统并进行文件传输】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言使用步骤总结 前言 一般来说,windows自带远程桌面,使用的RDP协议,Linux上支持RDP协议的软件很多,常用的是Remmi…

Java 网络编程之TCP(五):分析服务端注册OP_WRITE写数据的各种场景(二)

接上文 二、注册OP_WRITE写数据 服务端代码: import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.S…

【cf】Codeforces Round 941(Div.2)题解 A - D

前三题出的最快的一次&#xff0c;但是d没出 A. Card Exchange 只要有一种颜色大于等于 k&#xff0c;那就是 k-1&#xff0c;否则就是 n #include <bits/stdc.h>using namespace std;#define int long long using i64 long long;typedef pair<int, int> PII;…