当前位置: 首页 > news >正文

TCP如何保证传输可靠性

TCP协议传输的特点主要就是面向字节流、传输可靠、面向连接。这篇博客,我们就重点讨论一下TCP协议如何确保传输的可靠性的。

确保传输可靠性的方式

TCP协议保证数据传输可靠性的方式主要有:

  • 校验和

  • 序列号

  • 确认应答

  • 超时重传

  • 连接管理

  • 流量控制

  • 拥塞控制

校验和

计算方式:在数据传输的过程中,将发送的数据段都当做一个16位的整数。将这些整数加起来。并且前面的进位不能丢弃,补在后面,最后取反,得到校验和。 发送方:在发送数据之前计算检验和,并进行校验和的填充。 接收方:收到数据后,对数据以同样的方式进行计算,求出校验和,与发送方的进行比对。

这里写图片描述

注意:如果接收方比对校验和与发送方不一致,那么数据一定传输有误。但是如果接收方比对校验和与发送方一致,数据不一定传输成功。

确认应答与序列号

序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。 确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。

这里写图片描述

序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一。

超时重传

在进行TCP传输时,由于确认应答与序列号机制,也就是说发送方发送一部分数据后,都会等待接收方发送的ACK报文,并解析ACK报文,判断数据是否传输成功。如果发送方发送完数据后,迟迟没有等到接收方的ACK报文,这该怎么办呢?而没有收到ACK报文的原因可能是什么呢?

首先,发送方没有介绍到响应的ACK报文原因可能有两点:

  1. 数据在传输过程中由于网络原因等直接全体丢包,接收方根本没有接收到。

  2. 接收方接收到了响应的数据,但是发送的ACK报文响应却由于网络原因丢包了。

TCP在解决这个问题的时候引入了一个新的机制,叫做超时重传机制。简单理解就是发送方在发送完数据后等待一个时间,时间到达没有接收到ACK报文,那么对刚才发送的数据进行重新发送。如果是刚才第一个原因,接收方收到二次重发的数据后,便进行ACK应答。如果是第二个原因,接收方发现接收的数据已存在(判断存在的根据就是序列号,所以上面说序列号还有去除重复数据的作用),那么直接丢弃,仍旧发送ACK应答。

那么发送方发送完毕后等待的时间是多少呢?如果这个等待的时间过长,那么会影响TCP传输的整体效率,如果等待时间过短,又会导致频繁的发送重复的包。如何权衡?

由于TCP传输时保证能够在任何环境下都有一个高性能的通信,因此这个最大超时时间(也就是等待的时间)是动态计算的。

在Linux中(BSD Unix和Windows下也是这样)超时以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。重发一次后,仍未响应,那么等待2500ms的时间后,再次重传。等待4500ms的时间继续重传。以一个指数的形式增长。累计到一定的重传次数,TCP就认为网络或者对端出现异常,强制关闭连接。

连接管理

连接管理就是三次握手与四次挥手的过程,在前面详细讲过这个过程,这里不再赘述。保证可靠的连接,是保证可靠性的前提。

流量控制

接收端在接收到数据后,对其进行处理。如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。

在TCP协议的报头信息当中,有一个16位字段的窗口大小。在介绍这个窗口大小时我们知道,窗口大小的内容实际上是接收端接收数据缓冲区的剩余大小。这个数字越大,证明接收端接收缓冲区的剩余空间越大,网络的吞吐量越大。接收端会在确认应答发送ACK报文时,将自己的即时窗口大小填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值的改变进而改变自己的发送速度。如果接收到窗口大小的值为0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。 这里写图片描述

注:16位的窗口大小最大能表示65535个字节(64K),但是TCP的窗口大小最大并不是64K。在TCP首部中40个字节的选项中还包含了一个窗口扩大因子M,实际的窗口大小就是16为窗口字段的值左移M位。每移一位,扩大两倍。

拥塞控制

TCP传输的过程中,发送端开始发送数据的时候,如果刚开始就发送大量的数据,那么就可能造成一些问题。网络可能在开始的时候就很拥堵,如果给网络中在扔出大量数据,那么这个拥堵就会加剧。拥堵的加剧就会产生大量的丢包,就对大量的超时重传,严重影响传输。

所以TCP引入了慢启动的机制,在开始发送数据时,先发送少量的数据探路。探清当前的网络状态如何,再决定多大的速度进行传输。这时候就引入一个叫做拥塞窗口的概念。发送刚开始定义拥塞窗口为 1,每次收到ACK应答,拥塞窗口加 1。在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。

拥塞窗口的增长是指数级别的。慢启动的机制只是说明在开始的时候发送的少,发送的慢,但是增长的速度是非常快的。为了控制拥塞窗口的增长,不能使拥塞窗口单纯的加倍,设置一个拥塞窗口的阈值,当拥塞窗口大小超过阈值时,不能再按照指数来增长,而是线性的增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。 这里写图片描述

拥塞控制是TCP在传输时尽可能快的将数据传输,并且避免拥塞造成的一系列问题。是可靠性的保证,同时也是维护了传输的高效性。

总结TCP可靠性表现在以下七个方面:

1、应用数据被分割成TCP认为最适合发送的数据块。(这和UDP完全不同,应用程序产生的数据报长度将保持不变)。

2、确认响应:对于一个收到的请求,将发送一个确认。这个确认通常要延迟几分之一秒。

2、超时重传: 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。 3、TCP给发送的每一一个包进行编号 ,接收方对数据包进行排序,把有序数据传送给应用层。(TCP报文段作为IP数据报来传输,IP数据报的大刀可能会失序,因此TCP报文段的到达也可能会失序,如果必要,TCP将对收到的数据进行重新排序)。 4、校验和: TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错, TCP将丢弃这个报文段和不确认收到此报文段。 5、IP数据报会发生重复,TCP的接收端会丢弃重复的数据。 6、流量控制: TCP连接的每一方都有固定大小的缓冲空间 , TCP的接收端只允许发送端发送接收端缓冲区能接纳的我数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。

字节流服务::
 两个应用程序通过TCP连接交换8bit字节构成的字节流。TCP不在字节流中插入记录标识符。我们将这称为字节流服务(bytestreamservice)。

7、拥塞控制:当网络拥塞时,减少数据的发送。

相关文章:

  • TCP协议-如何保证传输可靠性
  • syn洪水攻击
  • vlan简述
  • ATM + 购物车项目开发
  • 注释文档 __doc__
  • __call__的使用
  • __init__ 和 __new__(重点)
  • __str__ 和 __repr__
  • __module__ 和 __class__
  • __slots__ 和 __dict__
  • __all__
  • 实现迭代器__iter__ 和 __next__
  • __len__
  • __hash__
  • __eq__
  • HTTP中GET与POST的区别 99%的错误认识
  • JavaScript DOM 10 - 滚动
  • javascript面向对象之创建对象
  • JavaScript设计模式系列一:工厂模式
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Median of Two Sorted Arrays
  • ReactNativeweexDeviceOne对比
  • SpiderData 2019年2月25日 DApp数据排行榜
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 给初学者:JavaScript 中数组操作注意点
  • 前端性能优化--懒加载和预加载
  • 树莓派 - 使用须知
  • 异常机制详解
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (c语言)strcpy函数用法
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (待修改)PyG安装步骤
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (接口封装)
  • (离散数学)逻辑连接词
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (算法设计与分析)第一章算法概述-习题
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • *Django中的Ajax 纯js的书写样式1
  • .NET 4.0中的泛型协变和反变
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .Net Remoting常用部署结构
  • .NET 读取 JSON格式的数据
  • .NET下的多线程编程—1-线程机制概述