TCP协议策略

news2024/9/23 9:22:10

TCP可靠性

基于序号的确认应答(ACK)机制

TCP保证可靠性最核心的机制就是基于序号的确认应答机制。

TCP并不是百分之百可靠的,但是只要一条消息有应答,那么我们就可以确定该消息100%被对方收到了,这就是确认应答的意义。

可靠性不仅仅是保证被对方收到,还需要保证按序到达,这取决于32位序号/32位确认序号字段。

  • 如何理解确认应答机制

我们可以把TCP的缓冲区看作是一个数组:

在这里插入图片描述

那么数组的下标就相当于OS给每个字节的数据标好了序号。

例如:应用层发送0-1000的字节到缓冲区,那么发送区就将0-1000下标的数据发到对方主机,然后对方会给你回应1001,意味着这批数据已经接收成功,下一次发送的起点是1001。

滑动窗口

刚才讨论了确认应答策略, 对每一个发送的数据段, 都要给一个ACK确认应答。 收到ACK后再发送下一个数据段。这样做有一个比较大的缺点, 就是性能较差。尤其是数据往返的时间较长的时候。

例如一次报文传输确定2001-3000,第二次确定3001-4000

既然这样一发一收的方式性能较低, 那么我们一次发送多条数据, 就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)

例如2001-3000、3001-4000、4001-5000一起发送,发送前三个段的时候无需等待ACK,直接发送。

收到第一个ACK后, 滑动窗口向后移动, 继续发送第五个段的数据。依次类推

在这里插入图片描述

具体发多少呢?和对方的接收能力有关。

这个过程通过滑动窗口来完成:

操作系统内核为了维护这个滑动窗口, 需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答; 只有确认应答过的数据, 才能从缓冲区删掉

滑动窗口本质是发送缓冲区的一部分。

根据滑动窗口,缓冲区可以分为三部分:

在这里插入图片描述

滑动窗口是可以增大或缩小的(一般是四等分),取决于对方的接受能力。强相关。

比如对端收到了数据,但是用户层没有读,那么缓冲区承受量减小,那么客户端根据其报文里的16位窗口大得知它的承受力减小了,对应的客户端滑动窗口也会减小。反之也会扩大一次发送多个数据

  • 如何理解滑动窗口大小

滑动的本质是数组指针++,所以窗口大小改变其实是:

1.start+=确认序号,也就是说左边界走(说明对方缓冲区不够了,此时发送端的数据一次传送量要减少)
2.end+=对方通告的窗口大小,也就是右边界走(说明对方的缓冲区足够)
向右滑动:确认前面的数据已经收到以后,向右滑动,是不可能向左滑的。

  • 如果丢包怎么办
  1. 如果是ACK丢包了:

这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认。

例如:1-4-7-10
万一中间的数据4-7丢包了,并且此时的接收到的序号只能收到截止到前面的数据1-3。就会进行到超时重传

万一中间的数据丢包了,但是此时的接受到的序号依然收到了1-3和7-10,说明此时对端已经收到了全部数据,只是回复的ack被
丢失了。此时也是默认数据传输完成的。

  1. 如果是数据包丢了:

快重传机制

当某一段报文段丢失之后, 发送端会一直收到 1001 这样的ACK, 就像是在提醒发送端 "我想要的是 1001"一样。

如果发送端主机连续三次收到了同样一个 “1001” 这样的应答, 就会将对应的数据 1001 - 2000 重新发送。这个时候接收端收到了 1001 之后, 再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已经收到了, 被放到了接收端操作系统内核的接收缓冲区中。

但是由于中间有丢包,所以接收到(2001-7000)的数据的时候,返回的ACK一直都是"1001"的应答,直到收到了1001的数据包,才继续接着当前最高数据的应答发送(此时也就是7001)。

所以说,数据的传输主要是看对端究竟有没有实打实收到数据,如果没收到,就算后面的数据对端也收到了,那么丢失的数据的序号也是传不过来的,序号也是从它从最开始连续收到的最长的数据的序号。

流量控制策略

接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。

因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(Flow Control)。

接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发送端。

窗口大小字段越大, 说明网络的吞吐量越高。

接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端。发送端接受到这个窗口之后, 就会减慢自己的发送速度。如果接收端缓冲区满了,就会将窗口置为0。 这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

  • 接收端如何把窗口大小告诉发送端呢?

TCP首部中, 有一个16位窗口字段, 就是存放了窗口大小信息;

如果过了超时重发的时间,还没有收到窗口更新的通知,client端会发送一个窗口探测的包。 一旦这个包丢失,会导致无法继续进行通信,所以client会时不时发送窗口探测包。

  • 16位数字最大表示65535, 那么TCP窗口最大就是65535字节么?

实际上, TCP首部40字节选项中还包含了一个窗口扩大因子M, 实际窗口大小是 窗口字段的值左移 M 位。

超时重传机制

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

在这里插入图片描述

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

但是, 主机A未收到B发来的确认应答, 也可能是因为ACK丢失了:

在这里插入图片描述

因此主机B会收到很多重复数据,那么TCP协议需要能够识别出那些包是重复的包,并且把重复的丢弃掉。这时候我们可以利用32位序列号, 就可以很容易做到去重的效果。

  • 那么, 超时的时间如何确定?

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

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

Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时时间都是500ms的整数倍。

如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传。

如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭链接。

拥塞控制

虽然TCP有了滑动窗口, 能够高效可靠的发送大量的数据. 但是如果在刚开始阶段就发送大量的数据, 仍然可能引发问题.

因为网络上有很多的计算机, 可能当前的网络状态就已经比较拥堵. 在不清楚当前网络状态下, 贸然发送大量的数据,是很有可能引起雪上加霜的.

TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据

  • 拥塞窗口

拥塞窗口 = min(拥塞窗口,对端窗口)

发送开始的时候, 定义拥塞窗口大小为1;每次收到一个ACK应答, 拥塞窗口加1;
每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗口;

像上面这样的拥塞窗口增长速度, 是指数级别的. “慢启动” 只是指初使时慢, 但是增长速度非常快

为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍.此处引入一个叫做慢启动的阈值。当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长

这里采用知乎 @奔跑的蜗牛 的图片:
在这里插入图片描述

  • 当TCP开始启动的时候, 慢启动阈值等于窗口最大值;
  • 在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1;

少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;

拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案。

延迟应答

如果接收数据的主机立刻返回ACK应答, 这时候返回的窗口可能比较小

  • 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
  • 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
  • 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M

在这里插入图片描述

一定要记得, 窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率。

那么所有的包都可以延迟应答么? 肯定也不是

  • 数量限制: 每隔N个包就应答一次;
  • 时间限制: 超过最大延迟时间就应答一次

具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间取200ms

总结

可靠性:

  • 校验和
  • 序列号(按序到达)
  • 确认应答
  • 超时重发
  • 连接管理
  • 流量控制
  • 拥塞控制

提高性能:

  • 滑动窗口
  • 快速重传
  • 延迟应答
  • 捎带应答

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

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

相关文章

MOSS模型量化版部署过程

文章目录 项目背景配置环境与准备部署推理命令行部署报错1报错2: 网页版部署 项目背景 2023年4月21日,复旦大学自然语言处理实验室正式开放MOSS模型,是国内首个插件增强的开源对话大语言模型。MOSS 相关代码、数据、模型参数已在 GitHub 和 …

【键入网址到网页显示】

HTTP 对 URL 进行解析之后,浏览器确定了 Web 服务器和文件名,接下来就是根据这些信息来生成 HTTP 请求消息了。 http://www.server.com/dir1/file1.html http:访问数据的协议 www.server.com:服务器 dir1:目录名 file1.html:文件名生产 HTTP 请求信息…

SpringCloud-10_Alibaba Nacos

SpringCloud系列 SpringCloud-9、SleuthZipkin SpringCloud-8、Gateway网关服务 SpringCloud-7_OpenFeign服务调用 SpringCloud-6_Ribbon负载均衡 SpringCloud-5_模块集群化 文章目录 SpringCloud系列Nacos基础Nacos是什么?Nacos下载&运行 创建Nacos服务提供者…

JavaScript:哈希表

文章目录 哈希表242. 有效的字母异位词思路补充:JavaScript String charCodeAt() 方法代码详细分析 349. 两个数组的交集代码分析补充:JavaScript Set 对象思考一下哈希是什么?什么时候使用?补充:js 数组 map() 基本用…

github使用workflow工作流git push后自动打包部署github pages

workflows介绍 根目录新建.github/workflows/docs.yml .github/workflows/ 目录是用于存放 GitHub Actions 工作流程文件的目录,该目录的文件名必须以 .yml 或 .yaml 为后缀名,否则 GitHub 将无法识别该文件为工作流程文件。这些工作流程文件可用于自动…

速锐得基于能源油气生产智能监控的物联网应用

自2016年速锐得基于商用车国六环保排放监控管理开发以来,我们同时也接触了很多涉及商用车领域的深入项目,包括了大庆油田、山东能源、兖矿集团、陕北矿业等多家能源巨头在数字化、科技、无线远程控制、监控管理、生产效能等方面的智能化方向的趋势。 就目…

MySQL 字段为 NULL 的5大坑,大部分人踩过

数据库字段允许空值(null)的问题,小伙伴你遇到过吗? 在验证问题之前,我们先建一张测试表及测试数据。 构建的测试数据,如下图所示: 有了上面的表及数据之后,我们就来看当列中存在 NULL 值时,究…

基于RGB-D的6D目标检测算法

基于RGB-D的6D目标检测算法 本文参考了ITAIC的文章 A Review of 6D Object Pose Estimation 概览 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eQX8ke6j-1683188966051)(https://mezereon-upic.oss-cn-shanghai.aliyuncs.com/uPic/image-20230420…

如何理解信息化、数字化和智能化的概念?一文给你解惑!

如何理解信息化、数字化和智能化的概念? 前两年流行“信息化”,网上铺天盖地都是关于“信息化”的文章,这两年开始流行起“数字化”,于是铺天盖地都是“数字化”的文章,最近又开始大谈“智能化”...... 但点开那些文…

常见的5种项目管理问题类型

项目管理的5大影响素:时间、范围、成本、风险、质量。项目经理需要对这些因素进行均衡考量,并根据需要略有侧重,进行整体把握,即我们常说的均衡型管理风格。而忽略任何一因素,都会对项目产生极大影响。 常见的项目管理…

医院导诊图怎么做?目前比较好用的医院导航地图是哪一款?

现在很多的大医院,不只是越建越高,面积也越来越大,同时医院内部按照门诊、住院、放射等不同功能划分的区域也是越来越多,走进这些“超级医院”就像走进了迷宫一样,如何促使病患走进医院后,能迅速找到要去的…

19C RAC主库 to RAC备库搭建adg报错ORA-16047(修改19C RAC DB_UNIQUE_NAME )

文章目录 前言一、问题描述二、修改DB_UNIQUE_NAME1.查看集群配置2.将hip40实例从集群中移除3.修改db_unique_name4.将hip40dg实例添加到集群资源中5.重新启动实例 三、19C RAC 密码文件替换 前言 主库环境是19C RAC备库环境也是19C RAC,主库到备库做adg&#xff0…

移动端动态开发能力的由来和流派

移动端动态化的由来 “动态化”并不是最近几年才产生的名词,而是从从互联网诞生的初期,这个词就已经出现了。大家所认知的早期互联网,其实就是各种各类的“动态网站”,内容数据和页面外观都不是固定的,都是随着服务器…

Bash脚本中的Sleep命令到底有何妙用?

在编写Bash脚本时&#xff0c;有时需要在程序执行过程中加入一些等待时间&#xff0c;例如等待某个操作完成或等待某个进程退出。此时可以使用sleep命令来实现。 sleep命令可以让脚本暂停执行一段时间&#xff0c;其基本语法为&#xff1a; sleep <seconds>其中&#xf…

细数【SD-WEBUI】的模型:谁是最适合的模型从哪里找到它们

文章目录 &#xff08;零&#xff09;前言&#xff08;一&#xff09;基础模型&#xff08;Stable-Diffusion模型&#xff09;&#xff08;1.1&#xff09;ChilloutMix&#xff08;仿真&#xff09;&#xff08;1.2&#xff09;BasilMix&#xff08;仿真&#xff09;&#xff0…

如何使用 Linux Cron Job 优化WP-Cron以获得更好的性能

在本教程中&#xff0c;我将向您展示如何通过在 Linux 上用 Crontab 替换默认的 WP-Cron 触发机制来优化 WordPress 性能。 WordPress 使用 WP-Cron 来运行计划任务&#xff0c;许多用户已经在使用。 但它的工作方式并不理想。 在每次页面加载时&#xff0c;WP-Cron 检查计划…

在Centos7上安装和配置canal

1. 在 MySQL 数据库中创建 Canal 账户并为其授权 在安装 Canal 前&#xff0c;你需要在 MySQL 数据库中创建一个用于 Canal 连接的账户&#xff0c;并为该账户授予必要的权限。 以下是在 MySQL 数据库中创建 Canal 账户并为其授权的步骤&#xff1a; 登录 MySQL 使用以下命令…

B019_子查询篇

2022-4-30 18:11:32 通过本章学习,您将可以: 描述子查询可以解决的问题。 定义子查询。 列出子查询的类型。 书写单行子查询和多行子查询 MEGER INTO的使用 WITH 子句🏆CHAPTER 12 Subqueries & Merge Statements子查询和合并语句 子查询——嵌套在另一个查询中的查…

MyBatis:使用代码整合

文章目录 MyBatis&#xff1a;Day 04框架1. 依赖&#xff1a;pom.xml2. 外部配置文件&#xff1a;db.properties3. 核心配置文件&#xff1a;mybatis-config.xml4. 实体类5. 接口&#xff1a;xxxMapper.java6. 实现类&#xff1a;xxxMapper.xml7. 测试 MyBatis&#xff1a;Day …

DTC 2023回顾丨基于数据复制技术的多写多读数据库集群解决方案

在不久前结束的2023 DTC数据技术嘉年华中国数据库创新论坛上&#xff0c;GBASE南大通用8s产品经理郭茁老师分享了GBase 8s《基于数据复制技术的多写多读数据库集群解决方案》。 今天带大家一同回顾下本次演讲。 海量数据的存储和运算是目前行业内面临的一个重要问题&#xff0…