TCP如何保证可靠性,TCP如何实现可靠性传输的

2023-05-16

tcp 如何保证可靠性

大家都知道TCP是可靠性传输协议,既然是可靠的,就需要解决比如包丢失了、数据被破坏了、包重复了、乱序了等等这样的问题。下面将从几个方面介绍TCP的可靠性。

1. 校验和

TCP每一段报文都有校验和,这保证了报文不被破坏或篡改,如果收到的报文在校验过程中有差错,TCP 将丢弃这个报文段和不确认收到此报文段。

2.序列号与确认应答

TCP发送的每一个包都有一个序列号,这可以让接收方知道自己已经接收到了那些包,哪些包丢失了,重复的包也可以根据序号丢弃,并且根据序号将包排序,同时每一个发送的包都会返回一个确认应答消息,来确保消息被接收。

3.重传机制

TCP 实现可靠传输的方式之一,是通过序列号与确认应答,当发送端的数据到达接收主机时,接收端主机会返回一个确认应答消息,表示已收到消息,如果数据包丢失了,就会用重传机制解决。
重传机制分为超时重传、快速重传、SACK、D-SACK

  • 超时重传 :在发送数据时,设定一个定时器,当超过指定的时间后,没有收到对方的 ACK 确认应答报文,就会重发该数据。超时时间被称为RTO,一般略大于RTT,不过RTO是一个动态值,具体如何计算,有兴趣的可以自行查询。如果重传的包又超时了,那么再次重传时间隔为上一次代分倍数;即每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。

  • 快速重传 :超时重传的问题是要等超时时间后才会重传。快速重传不以时间为驱动,而是以数据驱动重传,服务器如果收到乱序的包,也给客户端回复 ACK,比如收到乱序的包 6,7,8,9 时,服务器全都发 ACK = 5,这样客户端就知道5丢失了,当客户端收到三个相同的 ACK 报文时,会在超时之前,重传丢失的报文段,而不需要等到计时器超时。

  • SACK 选择性确认 :快速重传只解决了超时时间的问题,假如有19个包要传,其中4和5丢失了,服务端收到了69的包后,都只给客户端响应缺少4,客户端这时有两种选择:1.重传单个包,这个时候只会重传4,再次等到三个ACK后才会重传5,这样效率就会很低;2.重传4之后的所有包,由于服务端已经收到6~9,重传一次就会造成资源的浪费。于是就有了选择性确认这种机制,这种方式需要在 TCP 头部 选项(在上一章节的TCP头部报文格式中有介绍) 字段里加一个 SACK 的选项,它可以将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据

4.滑动窗口

TCP 是每发送一个数据,就需要等待对方进行ACK确认应答,这显然会极大的影响传输的速率。在发送数据的时候,最好的方式是一下将所有的数据全部发送出去,然后一起确认。于是就引入了窗口的概念,这个所谓的窗口实际上是操作系统开辟的一个缓存空间,发送方在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答后,此时数据就可以从缓存区清除,同样接收方接收数据后也是放在这个缓存区中的,那么接收方缓存区还能接收多少数据,这个就是决定窗口大小的因素,如果发送方的数据超过接收方缓存区的大小,那会造成接收方数据溢出,这就会导致数据丢失。所以,通常窗口的大小是由接收方的窗口大小来决定的。发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。

发送方的滑动窗口

在这里插入图片描述

  • 1是已发送并收到 ACK确认的数据
  • 2是已发送但未收到 ACK确认的数据
  • 3是允许发送但尚未发送的数据,总大小在接收方处理范围内
  • 4是不允许发送的数据,总大小超过接收方处理范围

滑动窗口并不是固定的,它主要是根据接收方的接收情况,动态去调整窗口大小,然后来控制发送方的数据流量

零窗口

在接收方窗口大小变为0的时候,发送方就不能再发送数据了。但是当接收方窗口恢复的时候发送方要怎么知道那?在这个时候TCP会启动一个零窗口(TCP Zero Window)定时探测器,向接收方询问窗口大小,当接收方窗口恢复的时候,就可以再次发送数据

流量控制

发送方不能无限制的发数据给接收方,也要考虑接收方的处理能力,如果一直无限制的发数据给对方,但对方处理不过来,那么就会导致触发重发机制,从而导致网络流量的无端的浪费。为了解决这种现象发生,TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制。流量控制由滑动窗口协议实现,滑动窗口既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。

拥塞控制

有了流量控制为什么还需要拥塞控制?

流量控制:流量控制是针对接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。即防止发送方的数据填满接收方的缓存区。

拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况。即防止发送方的数据填满整个网络

在网络出现拥堵时减少数据包的发送,网络恢复后它又会增加数据包的发送,这就是拥塞控制。

拥塞窗口cwnd:是发送方维护的一个的状态变量,它会根据网络的拥塞程度动态变化的,只要网络中没有出现拥塞,拥塞窗口就会变大,当网络中出现了拥塞它就会变小。

如何知道网络拥塞?

只要发送方没有在规定时间内接收到 ACK 应答报文,也就是发生了超时重传,就会认为网络出现了拥塞。

拥塞控制算法:

  • 慢启动:TCP 在刚建立连接完成后并不知道网络情况,它会一点一点的提高发送数据包的数量来试探网络的情况,它的主要原理就是:当发送方每收到一个 ACK,拥塞窗口 cwnd 的大小就会加 1。当然也不可能无限制的增加拥塞窗口 cwnd 的大小,有一个叫慢启动门限 ssthresh (slow start threshold)状态变量,当cwnd 小于该值时就增加,大于等于该值时就会启动拥塞避免算法。慢开始算法只是在TCP连接建立时和网络出现超时时才使用

  • 拥塞避免算法:进入拥塞避免算法后,它的规则是:每当收到一个 ACK 时,拥塞窗口cwnd 增加 1/cwnd,假设cwnd现在是8,那么进入拥塞避免算法后,收到ACK时,它增加了1/8。也就是说增长变的缓慢了,即使缓慢的增长,它也是无限制的,这样网络就会慢慢进入了拥塞的状况,当出现包丢失,触发重传机制的时候,就进入了拥塞发生算法。

  • 拥塞发生算法:当网络出现拥塞,也就是会发生数据包重传,触发重传机制,前面我们知道重传机制分为超时重传和快速重传两种情况,当发生了超时重传时才会使用拥塞发生算法,此时它会将ssthresh 设置为cwnd/2 ,并将cwnd 重置为初始值。接着,就重新开始慢启动,慢启动是会突然减少数据流的。这种方式太激进会造成网络卡顿。当发生快速重传时,TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,则 ssthresh 和 cwnd 变化如下,cwnd = cwnd/2 ,也就是设置为原来的一半;ssthresh = cwnd。进入快速恢复算法

  • 快速恢复算法: 快速重传和快速恢复算法一般同时使用,进入快速恢复算法后,拥塞窗口 cwnd = ssthresh + 3,重传丢失的数据包。快速恢复是针对拥塞发生后对慢启动的优化。

在这里插入图片描述

tcp 粘包问题

TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,导致数据包不能完整的体现发送的数据。导致TCP粘包的问题可能是发送方,也可能是接收方。

发送方

小数据包加剧了网络带宽的浪费,为了解决这个问题,引入了Nagle算法,该算法的思路是延时发送数据,它会将多个小的数据包合并成一个大的包一次性发送出去,以达到提升网络传输效率的目的。但是接收方并不知晓发送方合并的数据包,而且数据包的合并在TCP协议中是没有分界线的,所以这就会导致接收方不能还原其本来的数据包,这就会造成粘包问题。

接收方

接收数据方的应用层没有及时读取接收缓冲区中的数据,导致后面的数据包发送过来到达了缓存区,这样接收方的应用层读取缓存区数据时粘连了其他组的数据包。

还有如:要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包问题。

如何解决?
  • 发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。
  • 发送固定长度的消息(不够的可以通过补0填充)这样接收端每次从接收缓冲区中读取固定长度的数据就可以了,但是这种方式灵活性不高,实际中很少用
  • 添加特殊字符作为边界,可以在两个用户消息之间插入一个特殊的字符串,这样接收方在接收数据时,读到了这个特殊字符,就把认为已经读完一个完整的消息。例如:HTTP 通过设置回车符、换行符作为 HTTP 报文协议的边界。需要注意的是,如果刚好消息内容里有这个特殊字符则需要进行转义或者在特殊字符之后加上校验数据等。

rpc是什么?

RPC即远程过程调用,通常包含传输协议 和 序列化协议,传输协议:可以基于http协议实现、也可以基于tcp协议实现。序列化协议:有基于文本编码的 json 协议;也有二进制编码的 protobuf、hession 等协议

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TCP如何保证可靠性,TCP如何实现可靠性传输的 的相关文章

  • Logback

    logback logback 与 log4f出自同一作者 logback是作者对log4j的升级 它实现了slf4j slf4j是 simple log face for java 的缩写 我们要入门logback 搞懂几个核心类就可了
  • 取消与关闭

    取消与关闭 两方面 1 线程池的关闭 线程池的关闭 线程池给了两个方法 一个是shutdown 一个是shutdownnow 前者会把队里的任务给执行完 xff0c 且拒绝再进来的任务 而后者会将队里没有执行的任务返回 xff0c 且让正在
  • Linux 的文件的基本属性

    Linux 的文件的基本属性 1 两个指令 chown 修该所属用户与组合 chmod 修改用户的权限 首先这两个指令很重要 xff0c 我们以后会经常用到 xff0c 其次 xff0c 这两个指令也引出的两个概念 一个文件一定属于某个用户
  • Linux的用户和用户组

    Linux的用户和用户组 两个文件 我们学习Linux的用户和用户组可以从两个文件开始 1 passwd 如上图 这个配置文件 在 etc passwd路径下 每一行表示一个用户 1 1 每一行的结构 user name x uId gId
  • kalibr安装采坑过程

    前言 有两种方式进行kalibr标定 一种是编译好的kelibr cde xff0c 另一种是源码编译 xff0c 使用rosrun运行 我推荐源码安装方式 一 kalibr cde方式 想使用kalibr cde见如下过程 软件 我使用了
  • Linux 系统目录结构

    Linux 系统目录结构 虽然最近一直在使用docker来部署一些中间件或者服务 xff0c 但是还是会在宿主机中创建一些挂载 xff0c 这就涉及到我们应该把这些挂载文件放在哪里比较合适的问题 现在我们来认识下Linux的系统目录结构 先
  • 克拉拉与太阳

    克拉拉与太阳 当乔西要去读大学 xff0c 最后一次拥抱了克拉拉后离开 xff0c 我他妈真的哭了 克拉拉不应该是只是一个东西 xff0c 不应该被用完后就被抛弃 xff0c 不应该这样的 fuck the world 克拉拉最后独自在堆厂
  • 动物农村 读后感

    pig 在读完1984后 xff0c 我又马不停蹄的翻开了 动物农场 我怀恋苏联 xff0c 我觉得那是一个美丽的梦 xff0c 哪个国家所有的一切都属于人民 我想从这本书里找到红色梦想破碎的答案 农场里的动物在一天受到了老上校的思想启蒙
  • 哈士奇与藤原拓海

    哈士奇与藤原拓海 有的哈士奇是悲伤的 当我看到它的时候 xff0c 它像一摊被雨淋过的泥巴 xff0c 有气无力的趴着 它很瘦弱 xff0c 有几团毛似乎要脱落了 我蹲下来 xff0c 它只撇了我一眼 xff0c 它的眼睛是蓝色的 xff0
  • docker 镜像的复制

    docker 镜像的复制 有时候我们打的镜像需要从一台服务器传到另一台服务器 xff0c 但是奈何公司的服务器是只能连接内网的 这时候我们就需要能对docker的镜像进行复制 粘贴 整体思路就是 先在本地对镜像打包 然后通过ftp工具传到
  • FastDFS 搭建与客户端编写

    FastDFS 搭建与客户端编写 文件服务器 服务器搭建 https github com qbanxiaoli fastdfs 客户端编写 依赖 span class token tag span class token tag span
  • Linux 常用命令

    常用命令 1 yum 1 1 简介 yum 全称 xff08 Yellow dog Updater Modified 他是一个sheel前端软件包管理器 基于RPM包管理 xff0c 能够从指定的服务器自动下载RPM包并且安装 xff0c
  • 面对idea无厘头问题的两板斧

    1 啥都正常但是飘红 今天工程 所有import都飘红 但是 编译和运行都正常 解决 File gt Invalide Cache 2 工程结构不能识别 在idea中工程目录信息是控制在 idea 文件夹下面的 xff0c 有时候我们在一个
  • 开发中遇到的英语单词

    工作英语 metrics 指标resiliency 弹性 exchange 交换机 本来是交换 但是在系统中可以理解为邮局 即接受消息并发送消息的地方fuss 麻烦primitive 原始的 简陋的declarative 声明式的Relay
  • 来简单认识下简单的布隆过滤器

    布隆过滤器 1 简介 布隆过滤器是一种数据结构 主要由 一个 bit数组和一组hash函数组成 1 1优点 占用空间小 xff0c 效率高 1 2缺点 对于判断存在 是一个概率事件 而不是确定事件 2 作用 用来告诉我们 某个量 在一个量很
  • Gazebo 9 参考手册

    Gazebo参考文档 gazebo plugin参数含义
  • 手写一个布隆过滤器

    span class token keyword public span span class token keyword class span span class token class name BloomFilter span sp
  • INVALID TASK ‘.TEST.SKIP=TRUE’: YOU MUST SPECIFY A VALID LIFECYCLE PHASE […]

    问题 当我们在用如下命令行进行编译时 mvn Dmavne test skip span class token operator 61 span ture clean span class token function install s
  • 回到Zookeeper

    回到Zookeeper 1 藕花深处 平时会花时间学习Redis RocketMQ Motan Dubbo xff0c Kafka等中间件 xff0c 它们各有各的概念 xff0c 各有各的用途 我自认为自己在编程学习上并没有什么天分 xf
  • ChatGPT帮我实现LRU

    1 内存受限 不知道从什么时候开始 xff0c 什么东西都有了限制 xff0c 一个咖啡杯只能装下500ml水 xff0c 一块新买的内存也被标好了容量 xff0c 姑娘的心里再装不下另一个人 xff0c 我开始怀疑有什么东西是可以无限的

随机推荐