【网络】传输层协议TCP

目录

四位首部长度

序号

捎带应答

标记位

超时重传机制

连接管理机制(RST标记位)

三次握手及四次挥手的原因


TCP的全称是传输控制协议(Transmission Control Protocol),也就是说,对于放到TCP发送缓冲区中的数据,如何发,什么时候发,出错了怎么办,这些都是有TCP协议控制的

下面是TCP报文的基本格式

标准报头是20个字节,并且在传输层,并不会像我们在应用层一样还需要序列化,传输层直接发送的就是结构化的数据,因为这样发送成本是最低的,发送带宽最小。那它不是会有跨平台,大小端的问题吗?Linux内核中对它进行了处理:

不同的客户端都同时可以基于TCP协议向服务器发送信息,那么OS中就会存在很多收到的报文,这些报文可能正在网络层或数据链路层中,还没有拷贝到传输层的接收缓冲区,可能就在缓冲区中,还没来的及处理,总之各种情况

那么OS就要对大量的已经收到的,但是暂未处理的报文进行管理,如何管理呢?先描述再组织

而描述这种报文的结构体就叫做struct sk_buffer,它里面存有指针,就指向存着报文的内存空间,对于每层协议来说,报头在前面,正文在后面,我们如果要剥离报头,只需要指针向后移动一定的字节数即可,添加报头就是向前移动。所以封装与解包本质就是指针移动,然后进行一定操作

四位首部长度

那下面来解释一下TCP报文中的4位首部长度:

这个长度指的是报头的20个字节加上选项的长度,并且基本单位是为4字节

也就是说4位能表示的最大数字是15,即报头+选项的最大长度是15*4=60字节,选项的范围是[0,40]

我们都说TCP协议是可靠的,它保证可靠性,具体体现是什么呢?

因为我们发到网络中的消息,我们根本不知道它去了哪里,我们如果想知道它有没有被对方收到,就只能看有没有收到应答

所以我们可以确定的是如果我收到应答,那么我发的消息对方肯定收到了。这依靠的就是确认应答机制:我收到了消息就要应答

所以可靠性是指:我能知道对方收到了我发的消息,同时我也得知道对方没收到我发的消息

发送数据和应答这些细节其实都是双方OS完成的,这也就是“传输控制协议”中“控制”的一个体现

序号

我们发送数据可以串行发,也就是发送一条等应答,然后再发下一条等应答……,但是这样效率太慢了

我们可以一次发多条,但是问题就来了,对方也给我很多应答,那如果有一条消息对方没收到,那我怎么知道是那一条消息呢?并且对方怎么判断那条消息在前,那条消息在后呢?(因为我的发送顺序并不一定是对方的接收顺序)

这个问题的解决方法就是报头中的序号,我们可以给消息带序号,对方收到了一堆消息也可以通过排序序号来知道我发的消息的顺序,然后再按顺寻处理数据即可,所以应答就要把确认序号带上,这个确认序号一般是发来消息的序号+1

确认序号的含义就是该确认序号之前的数据,对方已经全部收到了,下次发送请从确认序号开始

我们知道TCP是有发送缓冲区,并且TCP是面向字节流的,其实我们可以把这个缓冲区看成一个一定长度的char数组,那么缓冲区中每个字节其实都有自己的序号,这个序号就是下标,确认序号我们前面说就是发来的报头中的序号+1,那么新的序号其实就是确认序号+我要发送的报文的长度

捎带应答

TCP是支持全双工的,既要向对方发送消息,也要向对方发送应答,所以需要序号和确认序号两个

如果只发应答,只需要发一个报头(报头中添加确认序号)即可,那么我可不可以发送一个报文,其中既有应答(确认序号),又有我想给对方发的数据(序号和正文)呢?当然可以,我们叫做捎带应答

标记位

下面我们来解释TCP报头中的标志位:

为什么要有标志位呢?其实就是区分不同的TCP报文类型

就比如我们知道基于TCP通信时,客户端要connect服务器,这是发的报文就是建立连接的报文,同时还有正常通信的报文,还有close时断开连接的报文等等,这些报文类型都不同,那么为了区分这些报文类型,就有了标志位

下面我们简单通过三次握手这个过程来介绍三个标记位:ACK(确认标记位),SYN(同步标记位),FIN(断开连接标记位)

这个过程是我们在客户端调用connect后OS自动完成的,首先客户端向服务器发送带SYN标记位(即将此位 置为1)的报头,服务器收到后向客户端发送SYN+ACK的报头,客户端收到后向服务器发送ACK的报头,至此三次握手成功后服务器accept获取连接。我们将服务器置为监听状态是因为只有listen状态的服务器才能受理SYN的请求

双方建立好连接之后是要对这个连接进行管理的,用内核数据结构去管理,,这样就会消耗内存空间和时间。所以说维护连接是有成本的

下面是四次挥手的大致过程:这个过程也是OS自动完成的

先调用close的一方(A)要向对方发送FIN请求,对方(B)收到后会发送ACK,之后B会发送FIN请求,A收到后发送ACK

超时重传机制

这个机制其实在报头中是没有体现的,当我们向对方发送请求时,如果我们迟迟都收不到应答,我们只能主观的认为对方没收到数据(也有可能收到了,只不过对方的ACK可能没发过来,我们肯定要按最差情况处理),此时,我们就认为超时了,我们需要重传。

也就是说,如果我们发送的请求在一个时间段内都没有收到应答,就要触发超时重传机制。

那万一对方收到了呢?只不过是ACK没发过来,因为报头中是有序号的,对方可以根据这个序号进行去重

上面说一个时间段内,那这是多少时间呢?

因为网络的状态是动态的,TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个超时时间

Linux,超时以500ms为一个单位进行控制,等待时间以此是1*500,2*500,4*500,这样以指数形式递增,累积到一定的重传次数,TCP就会认为网络或对端主机出现异常,强制关闭连接

连接管理机制(RST标记位)

有这样一种情况,就是三次握手的第三次ACK发送之后丢掉了,这时客户端已经认为建立好连接了,但是服务器却没有建立好连接。

此时客户端都可以向服务器发送数据了,此时服务器因为没有建立好连接但是收到了数据,此时就会向客户端发送带有RST标记位的报头来表示reset(重置),即重新进行三次握手

所以RST这个标记位就是用来解决建立连接出现异常的问题的

三次握手及四次挥手的原因

三次握手:

如果一次就可以握手,那太扯了,因为客户端连应答都没有收到,连最基本的网络连通性都无法确认

两次的话服务器是比客户端先建立连接的,维护连接是有成本的,如果客户端是恶意连接的,疯狂发送SYN请求(SYN洪水攻击),那么服务器资源就会被浪费,从而导致真正想连接的用户无法连接

所以三次握手就是因为:

1.需要保证网络(信道)是健康的,三次握手,客户端服务器双方都会有一次确定的收发,他们就可以确认是全双工

2.确保双方OS是健康且愿意通信的

四次挥手:

它的原因其实和三次握手是一样的,关键就是四次挥手没有进行捎带应答,因为虽然比如客户端关闭连接,但是服务器还有消息要发。那么此时用户如何拿取数据呢?

首先一般应用层代码是有逻辑的,一般按照协议收完消息后才会close;其次,其实我们可以仅关闭写端,不关闭读端,是有这样的接口的

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

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

相关文章

docker基础篇(尚硅谷)

学习链接 docker1️⃣基础篇(零基小白) - 语雀文档 (即本篇) Docker与微服务实战(基础篇) Docker与微服务实战(高级篇)- 【上】 Docker与微服务实战(高级篇)- 【下】 文章目录 学习…

Spark RDD

概念 RDD是一种抽象,是Spark对于分布式数据集的抽象,它用于囊括所有内存中和磁盘中的分布式数据实体 RDD 与 数组对比 对比项数组RDD概念类型数据结构实体数据模型抽象数据跨度单机进程内跨进程、跨计算节点数据构成数组元素数据分片(Partitions)数据…

OmicsTools软件和R语言分析环境安装配置答疑汇总最新版

OmicsTools软件和R语言分析环境安装配置答疑汇总 前言提示 我开发了一款本地电脑无限使用的零代码生信数据分析作图神器电脑软件OmicsTools,欢迎大家使用进行生物医学科研数据分析和作图,不需要学编程写代码,分析次数没有限制,可…

java web调试时清理当前网址的缓存

java web调试时清理当前网址的缓存 背景 开发后端接口的时候,出现页面已经重新部署启动。但页面报错404的问题。询问前端同学后,发现是因为没有清理页面缓存导致的。特别在此记录。 清理页面缓存 操作方式 chrome浏览器 F12 > 应用 > 存储 &g…

分布式 ID 生成策略(二)

在上一篇文章,分布式 ID 生成策略(一),我们讨论了基于数据库的 ID 池策略,今天来看另一种实现,基于雪花算法的分布式 ID 生成策略。 如图所示,我们用 41 位时间戳 12 位机器 ID 10 位序列号&a…

解决edge浏览器无法同步问题

有时候电脑没带,但是浏览器没有同步很烦恼。chrome浏览器的同步很及时在多设备之间能很好使用。但是edge浏览器同步没反应。 在这里插入图片描述 解决方法: 一、进入edge浏览器点击图像会显示未同步。点击“管理个人资料”,进入后点击同步&…

【机器学习】14. 集成学习 ensemble: bagging, boosting, 随机森林 random forest

集成学习 ensemble: bagging, boosting, 随机森林 random forest 1. Ensemble 整体认知2. 使用Ensemble的原因3. 构建Ensemble 的方法4. Bagging(bootstrap aggregation)特点 5. BoostingAdaBoost整体算法思路 6. 比较7. 随机森林 1. Ensemble 整体认知 …

记录一次更新idea

一、官网下载安装包&#xff0c;拿所需版本 二、链接下载&#xff0c; 逐行仔细读readme.txt 三、执行script(unstall<->install)vbs、-javaagent:更改时记得

低代码平台如何通过AI赋能,实现更智能的业务自动化?

引言 随着数字化转型的加速推进&#xff0c;企业在日常运营中面临的业务复杂性与日俱增。如何快速响应市场需求&#xff0c;优化流程&#xff0c;并降低开发成本&#xff0c;成为各行业共同关注的核心问题。低代码平台作为一种能够快速构建应用程序的工具&#xff0c;因其可视化…

实现企业微信打卡月报与简道云的高效集成

实现企业微信打卡月报与简道云的高效集成 企业微信打卡月报同步到简道云 在企业管理中&#xff0c;员工的考勤数据是至关重要的一环。为了实现高效的数据管理和分析&#xff0c;我们需要将企业微信的打卡月报数据集成到简道云平台。本文将分享一个具体的技术案例&#xff0c;展…

【Redis】常见基本全局命令

一、Redis俩大核心命令 由于Redis是以键值对的形式进行数据存取&#xff0c;自然就离不开不断的存储和获取&#xff0c;而其所对应的命令则是set和get&#xff0c;如此说来二者为Redis的核心基础命令也不为过。 作用&#xff1a;用于存储Stirng类型的数据 返回&#xff1a;当…

GPT避坑指南:如何辨别逆向、AZ、OpenAI官转

市面上有些说自己是官转&#xff0c;一刀只需要1块甚至几毛钱&#xff0c;并声称官方倍率的&#xff0c;很大可能就是使用的是 逆向或Azure。 如何鉴别逆向 逆向的种类很多&#xff0c;主要分为3类 逆向不知名A| 镜像站或偷的 key。成本约等于0&#xff0c;调用聊天数据可能在…

【PnP】详细公式推导,使用DLT直接线性变换法求解相机外参

文章目录 &#x1f680;PnP1️⃣ 求解不考虑尺度的解2️⃣ 恢复解的尺度3️⃣ 另一种解法 &#x1f680;PnP PnP(Perspective-n-Point)是求解3D到2D点相机外参的算法。PnP算法有DLT直接线性变换、P3P三对点估计位姿、EPnP(Efficient PnP)、BA(Bundle Adjustment)光速法平差。这…

数据库基础介绍

前言&#xff1a; 在当今信息化、数字化的时代&#xff0c;数据库是支撑一切信息系统的核心基础设施。无论是金融机构的账户管理、电商平台的商品库存&#xff0c;还是社交媒体的用户信息&#xff0c;数据库都在背后扮演着关键角色数据库不仅用于存储和管理数据&#xff0c;更…

[Ansible实践笔记]自动化运维工具Ansible(一):初探ansibleansible的点对点模式

文章目录 Ansible介绍核心组件任务执行方式 实验前的准备更新拓展安装包仓库在ansible主机上配置ip与主机名的对应关系生成密钥对将公钥发送到被管理端&#xff0c;实现免密登录测试一下是否实现免密登录 常用工具ansibleansible—docansible—playbook 主要配置文件 Ansible 模…

Hash表算法

哈希表 理论知识&#xff08;本文来自于代码随想录摘抄&#xff09;什么是哈希常见的三种哈希结数组&#xff1a;set:map:其他常用方法或者技巧&#xff08;自己总结的&#xff09; 练习题和讲解有效的字母移位词349. 两个数组的交集1. 两数之和454. 四数相加 II15. 三数之和 总…

如何选择适合自己的 Python IDE

集成开发环境&#xff08;IDE&#xff09;是指提供广泛软件开发能力的软件应用程序。IDE 通常包括源代码编辑器、构建自动化工具和调试器。大多数现代 IDE 都配备了智能代码补全功能。在本文中&#xff0c;你将发现目前市场上最好的 Python IDE。 什么是 IDE&#xff1f; IDE…

为什么架构设计禁止IP直连?

什么是IP直连&#xff1f; IP直连指应用程序直接在代码中硬编码IP地址&#xff0c;比如&#xff0c;连接mysql数据库的数据库链接&#xff0c;如下的定义方式&#xff0c;就属于IP直连。 这种写法在开发环境中很常见&#xff0c;但是&#xff0c;在正式生产环境中&#xff0c;…

Linux shell编程学习笔记87:blkid命令——获取块设备信息

0 引言 在进行系统安全检测时&#xff0c;我们需要收集块设备的信息&#xff0c;这些可以通过blkid命令来获取。 1 blkid命令的安装 blkid命令是基于libblkid库的命令行工具&#xff0c;可以在大多数Linux发行版中使用。 如果你的Linux系统中没有安装blkid命令&#xff0c;…

构建生产级的 RAG 系统

对 RAG 应用程序进行原型设计很容易&#xff0c;但要使其高性能、健壮且可扩展到大型知识语料库却很困难。 本指南包含各种提示和技巧&#xff0c;以提高 RAG 工作流程的性能。我们首先概述一些通用技术 - 它们按照简单到复杂的顺序进行排列。然后&#xff0c;我们将更深入地研…