【网络编程】深入理解TCP协议一(三次握手四次挥手、标记位、确认应答机制、超时重传机制)

0000

TCP协议

  • 1.三次握手四次挥手
  • 2.TCP协议段格式
  • 3.标记位介绍
  • 4.确认应答机制
  • 5.超时重传机制

1.三次握手四次挥手

0001

  1. 当客户端发起连接请求时,SYN需要被设置位1,告诉服务器客户端希望建立一个链接
  2. 服务器收到响应之后会回复 SYN+ACK,表示确认了客户端地连接请求,同时服务器也会设置ACK标记位,该标记位表示服务器已经接受到了客户端地链接请求,并且已经做好了与客户端链接地 准备(大多数情况下都是,对历史报文的确认)
  3. 客户端回复ACK,表示确认。
  4. 当通信结束时,由客户端发起fin请求,表示断开请求

当客户端发起一个FIN(Finish)请求时,表示客户端希望关闭连接。此时,客户端的状态会从ESTABLISHED状态(已建立连接)变为FIN-WAIT-1状态。客户端进入FIN-WAIT-1状态后,它正在等待来自服务器的确认,以完成连接的正常关闭。
在TCP连接的正常关闭过程中,连接的一方会首先发送一个FIN请求,然后等待对方的确认。在这个等待状态中,客户端会处于FIN-WAIT-1状态。一旦客户端收到了服务器的确认,它会进入FIN-WAIT-2状态,然后等待服务器发起的关闭步骤。
所以,客户端并不是在发送FIN请求的那一刻就立刻变成FIN-WAIT状态。而是在发送FIN请求后,等待对方确认之后才会进入FIN-WAIT-1状态。接下来,客户端将等待服务器的FIN请求,然后完成连接的关闭过程。

  1. FIN_WAIT1和FIN_WAIT2状态的区别

FIN-WAIT-1 和 FIN-WAIT-2 是 TCP 连接的两个不同状态,它们之间的主要区别在于等待的事件和条件:
FIN-WAIT-1状态:
进入条件:客户端在发送了一个FIN(Finish)请求后,进入FIN-WAIT-1状态。
事件和等待条件:客户端正在等待来自服务器的ACK(确认)以确认其关闭请求。在这个状态下,客户端等待服务器确认关闭请求,以便安全地关闭连接。
FIN-WAIT-2状态:
进入条件:一旦客户端收到了服务器对自己的FIN请求的ACK确认,它就会进入FIN-WAIT-2状态。
事件和等待条件:在FIN-WAIT-2状态下,客户端等待服务器发起的FIN请求。客户端已经完成了主动关闭连接的操作,现在等待服务器也发出关闭请求,以便完成连接的正常关闭。
总结:
FIN-WAIT-1状态是客户端等待来自服务器的ACK确认,以确认自己的关闭请求。
FIN-WAIT-2状态是客户端等待服务器发起的关闭请求,以完成连接的正常关闭。客户端已经完成了主动关闭步骤。

  1. timewait状态

TIME-WAIT 状态是 TCP 连接的一种状态,它表示一个连接已经被正常关闭,但在这个状态下,操作系统仍然保留连接信息一段时间。TIME-WAIT 状态的存在是为了确保连接的可靠关闭和避免出现连接混淆。
TIME-WAIT 状态主要有以下两个作用:
确保可靠关闭连接: 在 TIME-WAIT 状态下,操作系统等待一段时间(称为 2MSL,Maximum Segment Lifetime,最大报文生存时间)才会清除连接信息。这段时间内,如果网络中还有之前的数据包在传输,这些数据包仍然能够正确地被关联到已关闭的连接,而不会与后续的新连接混淆。这样可以确保数据包按照正确的顺序到达,并且不会被误认为属于新连接。
处理延迟重复数据包: 在网络中,数据包可能会因各种原因而被延迟或复制。TIME-WAIT 状态能够处理延迟到达的 ACK 数据包。如果在 TIME-WAIT 状态下接收到与之前连接相关的 ACK 数据包,操作系统会忽略它们,以防止它们被误认为属于新连接。
总之,TIME-WAIT 状态是 TCP 连接管理的一部分,它有助于确保连接的可靠关闭,并维护连接信息,以应对网络中的延迟和复制数据包。它是 TCP 协议的一部分,设计用于提高连接的可靠性和稳定性。

当服务器最后一次回复ack的时候此时服务器状态会被置为LASTACK,表示不会再发消息给客户端,但是此时的客户端并不会马上关闭,保证可靠传输他会等上一段时间(服务器没拿完数据),最后在close链接。

2.TCP协议段格式

0002

  • 源端口号和目的端口号:表示数据是从哪个进程来, 到哪个进程去,通过这两个端口号,网络就能够将数据包准确地发送到目标或者服务器程序,这是TCP/IP协议实现端到端通信地关键一环。
  • 32位序号:是TCP协议为每个字节的数据进行的编号。这个编号是唯一的,也就是说,每一条数据都有一个唯一的32位序号。这个序号用于标识发送端每次发送的数据,这样接收端就能正确地将数据按照发送的顺序进行接收。
  • 而32位确认序号:是接收端对于发送端消息的应答序号。这个序号表明所有该序号之前的信息都被接收端成功接收。如果发送端发送了一条数据,接收端成功接收后,就会返回一个确认序号,表示所有该确认序号之前的数据都已经被成功接收。这个机制保证了数据的可靠传输,并且如果数据在传输过程中丢失或者损坏,可以进行重传。
  • 16位窗口大小

在 TCP 协议中,16 位窗口大小指的是 TCP 报文段中的窗口字段,它占用了 16 位(2 个字节)的二进制位数,用来表示发送方可以接收的字节数量。
窗口大小的概念是为了实现流量控制和拥塞控制而引入的。发送方和接收方都维护一个窗口大小的值,用来表示它们各自可以处理的数据量。窗口大小是动态调整的,根据网络条件和接收方的处理能力进行调整。
具体来说,当接收方希望发送方减缓发送速率时,它会将窗口大小减小,从而限制发送方发送的数据量。当接收方准备好接收更多数据时,它会增加窗口大小,允许发送方发送更多数据。
16 位窗口大小的字段允许窗口大小的范围从 0 到 65535 个字节,因此发送方可以发送的数据量也在这个范围内动态调整。这种机制有助于避免网络拥塞和提高网络效率,因为它允许发送方根据接收方的能力来调整发送速率,以保持网络的稳定性和可靠性。
总之,16 位窗口大小是 TCP 协议中用来进行流量控制的重要字段,它允许发送方和接收方动态地调整数据传输速率,以适应不同的网络条件和接收方的处理能力。

3.标记位介绍

  • SYN(Synchronize): SYN 标记位用于建立一个新的 TCP 连接。当客户端希望与服务器建立连接时,它会向服务器发送一个带有 SYN 标记位的 TCP 报文,这个过程称为 TCP 三次握手。SYN 标记位的序列号用于初始化连接的起始序列号。

  • ACK(Acknowledgment): ACK 标记位用于确认接收到的数据。当这个标记位被设置时,它表示该报文包含一个有效的确认号字段,确认了前面收到的数据。通常,除了在连接建立时的初始 SYN 报文外,其他 TCP 报文都会设置 ACK 标记位。

  • FIN(Finish): FIN 标记位用于关闭一个 TCP 连接。当一方希望关闭连接时,它会发送一个带有 FIN 标记位的报文,这个过程称为 TCP 四次挥手。发送 FIN 标记位表示该方不再发送数据,但仍愿意接收数据。

  • RST(Reset): RST 标记位用于强制关闭一个连接。当某些异常情况发生时,可以发送一个带有 RST 标记位的报文来迅速终止连接,而不进行正常的关闭过程。例如,当尝试连接一个未打开的端口时,对方会发送 RST 报文。

  • PSH(Push): PSH 标记位用于提示接收方立即将接收到的数据交给应用层,而不是等到缓冲区满后再交付。这对于实时数据或需要低延迟的应用场景非常有用。

双发在建立通信的时候,由于某些原因,接收端没及时把缓冲区的数据拿走,导致缓冲区满了,这时发送方就可以发送送PSH请求,让接收端马上把缓冲区数据拿走

  • URG(Urgent): URG 标记位用于标识报文中的紧急数据。当这个标记位被设置时,数据报文中的某些部分被标记为紧急,接收方应尽快处理这部分数据。URG 标记位通常与紧急指针字段一起使用,指示了紧急数据的位置。

报文在发送的时候,可能是乱序到达的,是一种不可靠传输,在有些特殊的应用场景,我们需要设置一些优先级更高的数据,但是正常传输的话不能满足优先级传输,此时就可以讲URG置1,按优先级处理 应用:当客户端和服务器异常的时候,客户端发送了大量的信息给服务器,但是这时由于各种原因,导致服务器异常,没能及时处理数据,客户端也没收到服务器的响应,此时客户端不知道还要不要给服务器发送消息,这时候就可以设置URG,发送一个确认请求(优先级高于前面的数据),及时给服务器,服务器马上响应,给客户端反馈原因

4.确认应答机制

TCP 协议通过确认应答机制来确保可靠的数据传输。这个机制包括以下几个重要的部分:
序列号和确认号: TCP 协议中的每个数据报文段都包含了一个序列号字段和一个确认号字段。发送方使用序列号来标识发送的数据,接收方使用确认号来确认已经接收到的数据。通过这两个字段的配合,TCP 可以精确地追踪传输的数据。

累积确认: 接收方通常会发送一个确认号,表示它已经成功接收到了这个确认号之前的所有数据。这个确认号是连续的,表明所有的数据都已到达。如果接收方收到了一个非连续的数据块,它会发送一个确认号,告诉发送方需要重传未收到的数据。

超时重传: 如果发送方在一定时间内没有收到接收方的确认应答,它会认为数据丢失或损坏,并触发重传机制。发送方会重新发送未被确认的数据,以确保数据的可靠性。

重复数据排除: 接收方在接收到重复的数据时会丢弃重复的部分,只接受首次接收到的数据。这是通过序列号和确认号来实现的,接收方可以识别出重复的数据。

选择性确认(SACK): TCP 协议支持选择性确认,允许接收方在确认报文中指定已经成功接收的数据块范围,而不仅仅是单一的确认号。这有助于提高网络的吞吐量和效率。

窗口控制: TCP 使用滑动窗口机制来调整发送方的发送速率。接收方会告诉发送方它的接收窗口大小,发送方会根据这个窗口大小来控制发送的数据量,以防止过多的数据拥塞网络。

流量控制: TCP 还提供了流量控制机制,允许接收方以自己的速率接收数据,以防止发送方发送速度过快导致数据丢失或溢出。流量控制通过 TCP 的滑动窗口机制实现。

总之,TCP 协议的确认应答机制是其可靠性的关键之一。通过序列号、确认号、重传、窗口控制等机制,TCP 可以确保数据的可靠传输,即使在不可靠的网络环境中也能够有效工作。这使得 TCP 成为广泛应用于可靠数据传输的协议,例如 Web 浏览、电子邮件、文件传输等。

结合图理解:
0003
TCP将每个字节的数据都进行了编号. 即为序列号:
0004
每一个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发. ** 这就是确认应答机制 **

5.超时重传机制

0006

  • 主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B;

  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发;

  • 但是, 主机A未收到B发来的确认应答, 也可能是因为ACK丢失了
    0007
    因此主机B会收到很多重复数据. 那么TCP协议需要能够识别出那些包是重复的包, 并且把重复的丢弃掉.
    这时候我们可以利用前面提到的序列号, 就可以很容易做到去重的效果.
    那么, 如果超时的时间如何确定?

最理想的情况下, 找到一个最小的时间, 保证 “确认应答一定能在这个时间内返回”.
但是这个时间的长短, 随着网络环境的不同, 是有差异的.
如果超时时间设的太长, 会影响整体的重传效率;
如果超时时间设的太短, 有可能会频繁发送重复的包;

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

Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时
时间都是500ms的整数倍.
如果重发一次之后, 仍然得不到应答, 等待 2500ms 后再进行重传.
如果仍然得不到应答, 等待 4
500ms 进行重传. 依次类推, 以指数形式递增.
累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接

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

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

相关文章

利用Semaphore实现多线程调用接口A且限制接口A的每秒QPS为10

前段时间在群里面发现有个群友抛出一个实际需求:需要通过一个接口拉取数据,这个接口有每秒10QPS限制,请问如何实现数据拉去效率最大化且限制调用拉取接口每秒10PQPS?我觉得这个需求挺有意思的,跟某群友讨论&#xff0c…

莫比乌斯召回系统介绍

当前召回系统只能召回相关性高的广告,但不能保证该广告变现能力强。莫比乌斯做了如下两点创新: 在召回阶段,引入CPM等业务指标作为召回依据在召回阶段,引入CTR模型,从而召回更多相关性高且变现能力强的广告 参考 百度…

leetcode 26.删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k ,你需要做…

mybatis-plus分页

ApiOperation(value "条件过滤分页查询列表")PostMapping("/list/conditions")public ResponseDTO<PageResultDTO<UnitManagementsEntity>> getAllUnitManagementsWithConditions(RequestBody PageParamDTO queryDTO,RequestParam(required …

Python---函数的几种参数

位置参数关键字参数 &#xff08;键值&#xff09;缺省参数 &#xff08;默认值必须写在最后&#xff09;不定长参数 &#xff08;1&#xff1a;位置传递 &#xff0c;2&#xff1a;关键字传递&#xff09;函数作为参数传递 &#xff08;计算逻辑的传递&#xff0c;…

微信小程序如何在切换页面后原页面状态不变

在微信小程序中&#xff0c;如果要实现在切换页面后原页面状态不变&#xff0c;可以通过以下几种方式来实现&#xff1a; 使用全局数据&#xff1a;可以将需要保持状态的数据存储在小程序的全局数据中&#xff0c;这样无论切换到哪个页面&#xff0c;都可以通过全局数据来获取…

5.k8s jenkins集成k8s一键发布案例

文章目录 前言一、jenkins配置1.1 jenkins配置git1.2 jenkins 配置maven1.3 jenkins配置java 二、jenkins流水线配置2.1.新增项目2.2 springboot项目配置git仓库2.3 springboot项目配置maven打包2.4 系统配置 ssh到hadoop1配置&#xff0c;也就是k8s的master节点2.6 springboot…

【多线程】常见的锁策略

常见的锁策略 1. 乐观锁 vs 悲观锁2. 读写锁 vs 普通互斥锁3. 重量级锁 vs 轻量级锁4. 自旋锁&#xff08;Spin Lock&#xff09;vs 挂起等待锁5. 公平锁 vs 非公平锁6. 可重入锁 vs 不可重入锁7. Synchronized8. 相关面试题 1. 乐观锁 vs 悲观锁 悲观锁&#xff1a; 总是假设…

安防监控系统/视频云存储EasyCVR平台视频无法播放是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

誉天在线项目~ElementPlus Tag标签用法

效果图 页面展现 <el-form-item label"课程标签"><el-tagv-for"tag in dynamicTags":key"tag"class"mx-1"closable:disable-transitions"false"close"handleClose(tag)"style"margin:5px;">…

Arcgis多值提取至点所有波段数值一样

Arcgis多值提取至点所有波段数值一样 问题描述 进行多值提取多波段后的结果&#xff0c;所有波段数值都是一样的。 原因 操作流程问题&#xff0c;输入栅格只选择了一个栅格文件 解决方案 实际上&#xff0c;每个波段都会对应一个栅格文件&#xff0c;要把这些添加进去 这…

进程地址空间(Linux虚拟内存机制)

文章目录 一.Linux进程地址空间的结构二.Linux管理进程地址空间的方式三.Linux进程使用物理内存的模型四.进程地址空间的存在意义 本章理论基于32位平台的Linux–kernel 2.6.32版本内核 一.Linux进程地址空间的结构 为了保证内存安全,现代操作系统不允许应用程序(进程)直接访问…

(二十八)大数据实战——Flume数据采集之kafka数据生产与消费集成案例

前言 本节内容我们主要介绍一下flume数据采集和kafka消息中间键的整合。通过flume监听nc端口的数据&#xff0c;将数据发送到kafka消息的first主题中&#xff0c;然后在通过flume消费kafka中的主题消息&#xff0c;将消费到的消息打印到控制台上。集成使用flume作为kafka的生产…

从零开发短视频电商 使用Spring WebClient发起远程Http调用

文章目录 依赖使用创建WebClient实例创建带有超时的WebClient实例示例 请求准备获取响应 高级过滤器自定义过滤器 自定义线程池自定义WebClient连接池开启日志错误处理最佳实践 示例异步请求同步请求上传文件重试过滤错误错误处理 参考 Spring WebClient 是 Spring WebFlux 项目…

基于Protege的知识建模实战

一.Protege简介、用途和特点 1.Protege简介 Protege是斯坦福大学医学院生物信息研究中心基于Java开发的本体编辑和本体开发工具&#xff0c;也是基于知识的编辑器&#xff0c;属于开放源代码软件。这个软件主要用于语义网中本体的构建&#xff0c;是语义网中本体构建的核心开发…

高阶导数的概念与公式

目录 高阶导数的概念 常用的高阶导数的公式 隐函数补充 反函数补充 高阶导数的概念 高阶导数是指一阶或二阶及以上的导数。这些导数可以通过连续进行一阶导数的计算来得到。然而&#xff0c;实际计算高阶导数时&#xff0c;存在一些问题&#xff0c;例如对抽象函数高阶导数…

遇见问题:使用mybaties向数据库中插入数据,idea显示插入成功,但是数据库中并没有数据变化?

遇见问题&#xff1a;使用mybaties向数据库中插入数据&#xff0c;idea显示插入成功&#xff0c;但是数据库中并没有数据变化? 可能的原因有几种&#xff1a; 没有提交事务&#xff1a;在使用 MyBatis 进行数据库操作时&#xff0c;需要手动提交事务。你可以在插入数据完成后…

北京映急物流有限公司 面试.net软件工程师岗位

请实现以下算法&#xff0c;语言不限&#xff0c;也可以是伪代码。 1.有一个数组 a[1000]存放了1000整数&#xff0c;这 1000 个数都大于等于 1&#xff0c;小于等于999&#xff0c;并且只有两个数是相同的,剩下的 998 个数均不相同。请写一个最优搜索算法&#xff0c;找出相同…

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一)

西门子S7-1200F或1500F系列安全PLC的组态步骤和基础编程(一) 第一部分:组态配置 具体步骤可参考以下内容: 如下图所示,新建一个项目后,添加一个安全型PLC,这里以1516F-3 PN/DP为例进行说明, 如下图所示,添加CPU完成后,可以看到左侧的项目树中比普通的PLC多了几个选项…

Markdown和PlantUML的基本使用

首先需要在VS Code中安装Markdown extention和plantUML插件 测试标题 这是测试标题&#xff0c;使用一个#号配合标题 测试1级标题 这是1级测试标题&#xff0c;使用2个#号配合标题 测试2级标题 这是2级测试标题&#xff0c;使用3个#号配合标题 这里是多级列表 Part A S…