网络原理(二)TCP的可靠传输

网络原理(一)目录

  • 网络原理
    • 应用层
    • 传输层
      • 先说UDP(不可靠传输)
      • 重点说明TCP(可靠传输)
        • 一、确认应答
        • 二、超时重传
        • 三、链接管理
          • 建立连接
          • 断开链接
        • 四、滑动窗口
        • 五、流量控制(也是保证可靠性的机制)
        • 六、阻塞控制
        • 七、延迟应答(效率机制)
        • 八、捎带应答(效率机制)
        • 九、面向字节流(粘包问题)
        • 十、异常情况(心跳包)

网络原理

网络协议的在实际运用是分为5层协议及:

  1. 应用层
  2. 传输层
  3. 网络层
  4. 数据链路层
  5. 物理层

这五层结构在,java 网络编程中已经有所现,具体用法具体实现的功能,都有。

应用层

这里主要的一个协议也是目前网络上最常用的一个协议,HTTP协议。

这层结构,决定数据要传输什么,拿到数据后如何使用。HTTP为什么是最长用的一个应用层协议,其本质就是在确定框架后,程序员可以在自定义一些协议,可控性和操控大大提升。

及约定数据报的数据格式,就是在自定义协议。

而如何约定?

  1. 确定要传输那些信息(根据需求走)
  2. 确定数据按照啥样的格式来组织。
  • 网络上传输的,本质都是二进制字符串,就需要将上述的穿输的信息整合为一个字符串。但是在传输内容的时候,一个我们需要的数据,其实和其他数据是合在一起的。我们要如何拿到所需要的数据。很简单,我们在传输数据的时候,设定一个符号,或者距离单位。锁定所需要的数据。

  • 比如我规定,属性之间用 ’,‘ 隔开 ,每个对象用 ‘\n’ 隔开,结束标志用 ’;‘ 隔开 。

  • 只要发送方发送数据按照这个格式传输,然后接收方,在解析数据的时候,用这个格式解析就好;

  • 在开发中,有一些特定的现成的格式。可以直接拿来使用。比如之前的一种典型的格式,xml ,还有现在用的比较多的一种格式。json,
    什么是json。
    {
    userId:100
    userPos:10-100
    }
    使用{}作为标识,{}里面的诺干个键值对,每个键值对用 ’,‘ ,分割,键值对,用 ’:‘ 分割。 键必须是字符串,值就可以是一个object。

传输层

先说UDP(不可靠传输)

这个就是UDP 的报文格式。
在这里插入图片描述
在这里插入图片描述

  • 端口是2个字节,所以端口可以取:0-- > 65535
  • 报文长度就局限了正文最大能装多少的内容。64KB。所以如果用UDP进行传输一个很长的数据,就需要包一个较大的数据,拆成很多分,用UDP传输。(很复杂)
    所以用UDP传输数据,不能太大,否则就会出现问题。
  • 校验和,是为了校验数据的准确的。在真实的网络传输中就会遇到很多问题。磁场,太阳风暴,等等。这些都会干扰数据的稳定。而校验和就是用来判定,当前的数据是否出错。(通常是设定一种特殊的算法,比如取正文中的一些字符,然后算出一个数据,然后传输完毕后在验证一次)

重点说明TCP(可靠传输)

TCP如何实现可靠传输?

一、确认应答

什么是确认应答呢?其实就很简单,比如网上购物,商家发货,货物根据你的信息发送货物,然后送到哪里并且,你确认了收货,然后平台就会将钱给商家,这就是一个很简单的应答模式。

在这里插入图片描述
这个模型有一个问题,就是网络的状况有很多种,会出现后发先至的问题。对应到上述的例子就是,遇到强降雨,但是后边的货车走了另一条路。走的就比之前的车要快。

异常状态
在这里插入图片描述
正常状态
在这里插入图片描述
如何解决这个问题?
此时就需要对消息进行编号。

  • 给发送的消息分配一个需要
  • 同时应答报文,给出一个确认顺序

在这里插入图片描述

协议格式:

在这里插入图片描述

TCP将每个字节的数据都进行了编号,基序列号。


在这里插入图片描述

  • 源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
  • 32位序号/32位确认号:后面详细讲;
  • 4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
  • 6位标志位:
    • URG:紧急指针是否有效
    • ACK:确认号是否有效
    • PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
    • RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
    • SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
    • FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
  • 16位窗口大小:后面再说
  • 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光
  • 包含TCP首部,也包含TCP数据部分。
  • 16位紧急指针:标识哪部分数据是紧急数据;
  • 40字节头部选项:暂时忽略;

在这里插入图片描述
首先接送方的序号和发送方的序号无关
确认序号 1001 的含义。

  1. 小于1001的数据,我已经收到
  2. 我接下来想要发送方从1001开始的数据

在之前说过,网络传输的时候,会有后发先至的情况,同样的这个也是。但是能,TCP在传输时会有序号,序号天然就有顺序,所以对于这种情况,只要在接收方接收前排序就好了。(优先级队列就能完成这个)、

对于TCP来说,自身也承担了这个整队的任务,TCP会有一个缓冲区(内核中的一个区域),每个socket都有自己的缓冲区。然后TCP就可以按照序号针对收到的消息进行针对。

如果一切顺利就可以应答了。可问题就是,现实并不顺利。比如丢包。

二、超时重传

那么什么是丢包呢?
传输数据的时候要经过各个节点,可是问题来了,一台机器节点的转发能力是有极限的,也就是说到达极限的机器,就可能会引起丢包的问题。(实时性的APP或者应用对于丢包的问题非常的敏感),如果丢包了接收方就收不到了。自然就不会返回ACK。

如何解决?

之前的逻辑,就是发送方发送消息会受到一个接收者的反馈的接收信息。但是丢包了,数据就不完整了。在队列里之前排好序的数据,因为丢包使得,序列并不完整。

此时因为序列并不完整,就不会交给接收者。然后序列就会等待,如果此时的序列等待时间长了,发送方迟迟拿不到应答。那么发送方就知道,传输出了问题,那么就会重新再发一次。直到拿到应答。(这个就叫超时重传)

有一个细节:

  • 数据直接丢失,接收方没收到,自然不会发 ack
  • 接收方接收到数据了,但是返回的ack 却丢了。

此时发送方分不清这些情况,只能重传。

可是此时,接收方已经在缓冲区中有了数据,再传一个,就重复了。此时接收方的缓冲区,会根据数据的序列,自动去重。保证应用程序中读到的数据任然只有一份

如果多次重复发送还没有收到ack 那么多半网络出了问题。主要是假设丢包率为10%,那么连续两次丢包,概率就是10% * 10%=1%

而以上这两种机制就是,TCP的可靠性保障。及:

  1. 确认应答
  2. 超时重传

三、链接管理

TCP创建链接:三次握手
TCP断开链接:四次挥手

建立连接

什么是三次握手?
握手是指通信双方,进行一次网络交互。相当于客户端和服务器之间,通过三次交互,建立连接关系(双方各自记录了对方的信息)
在这里插入图片描述
互相应答,确保双方的网络是完整的。并建立连接(有那么一滴滴可靠性的说法,但并不是)

等建立连接完毕,服务器 accept 把建立好的链接从内核拿到应用程序中。
在这里插入图片描述

  • 此时如果ACK 为 1 ,则表示当前的TCP数据报为一个应答报文
  • 此时如果SYN为 1 ,则表示当前的TCP数据报为一个同步报文
  • 如果ACK和SYN都是 1 ,则这个报文就是 SYN + ACK

做这么多。其实就是验证自己的发送能力和接收能力是否正常。

断开链接

什么是四次挥手?
通信的双方,各自给对方发一个FIN(结束报文),在各自给对方放回ACK

在这里插入图片描述
建立连接,一定是客户端发起,但是断开链接客户端和服务器都有可能。(并且通常ACK与FIN并不能重合)(FIN比特位位1的时候)

注意:
三次握手:ack与syn是同一个时机触发的(都是由内核完成)
四次握手:ack与fin内是不同时机出发的。前者由内核完成,而后者需要程序中 socke t的 close 方法才会触发fin、

在这里插入图片描述

四、滑动窗口

是为了解决,数据传输的效率问题。

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

可靠性的提升,往往代表,效率的损失。

在这里插入图片描述
可以看到,客户端A这边传输5000个字节,要应答四次。此时A就用了大量的时间去等待ACK

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

在这里插入图片描述
此时将数据进行批量发送。统一发送后,一起等待ACK的返回。这个批量传输的过程就是滑动窗口

等待的传输数据到达一定的数量,而这个批量等待的数据称为————》窗口大小

在这里插入图片描述
白色区域,相当于等待的窗口~~

批量发送了四个数据,就等待四个ACK。

这个批量发送也会出现问题。
比如:

  • 数据包以抵达,而ACK却丢了
    在这里插入图片描述
    这种情况,即使丢了这么多的ack,对于可靠性也没有任何影响。

确认序号的意思是指,该序号之前的数据都已经收到了,后一个 ACK 能表示前面的 ACK。(覆盖了)

  • 数据包就直接丢了
    在这里插入图片描述

解释:由于刚才1001 - 2000 这个数据丢了,所以接收方任然要索要1001,不会说因为收到的是2001-3000,就返回3001。接下来几次的数据 ack ,确认序号都是1001, B 再次向 A 反复索要 1001 这个数据,A这边识别到多个 1001 的请求,就知道 1001-2000丢了。于是 A 就重传了 1001-2000 这个数据。

当 A 1001-2000 这个数据重传后,B 收到了就会 传一个7001这个ACK,因为,数据只是缺了1001-2000这一段,补上之后,不用传关于这个段的 ACK,根据滑动窗口特点,后一个 ACK 就能表示他前面的数据已经到达 B。也就是,虽然1001-2000这一段没收到,但是其他的还在收啊。只是没有应答。补上了之后就开始应答。

这个重传的过程也叫:快速重传。

五、流量控制(也是保证可靠性的机制)

按道理来说,窗口越大,意味着,批量传输数据越多,也就意味着整体速度越快。但是数据多,就不意味着安全可靠。

数据一次性发的多,而快,一下子就把接收缓冲区给充满了。如果继续发送数据,此时就会丢包。这个时候,就需要控制一下流量

在这里插入图片描述
当ACK为1的时候,窗口大小字段就会生效。这里16位窗口是建议。

重要:发送方的窗口大小 = 流量控制 + 拥塞控制
在这里插入图片描述
如此就达成了阻塞的效果。

六、阻塞控制

滑动窗口大小 = 流量控制 + 拥塞控制

流量控制:平衡了接收方的处理能力
阻塞控制:衡量了传输路劲的处理能力

在java网络编程的哪一章中网络的传输是需要经过很多个节点的。如果任何一个设备,处理能力达到瓶颈,都会对整体的传输塑料产生明显影响。

而阻塞控制,就需要找到,衡量中间节点,传输的能力。怎么找?通过一次次实验,找到一个合适的发送速率

  1. 开始的时候,按照一个小的速率发送
  2. 如果不丢包,就可以扩大窗口的大小
  3. 如果丢包,就可以缩小窗口的大小

在这里插入图片描述
慢开始:刚开始传输会给一个非常小的窗口
指数规律增长:每一次扩大窗口,是翻倍成长。快速接近网络传输路径的能力瓶颈。
传输轮次:第一次发送,第二次发送。。。。
拥塞避免,“加法增大” :指数增长懂啊一定的阈值,就变成线性增长。避免一次性增加很多突然超出上限。
网络拥塞:增长到一定程度,出现丢包,认为当前的窗口大小,已经是传输的极限了。

七、延迟应答(效率机制)

TCP 可靠性的核心,是确认应答,ACK要发,但是不是立即发,而是稍微磨蹭一会再发,TCP中决定传输效率的关键元素就是,窗口大小。

在这里插入图片描述
此时服务器并不会立即返回一个ACK,也不一定要等到服务器将缓冲区里的数据全部拿出来,等待一下,然后偷偷的拿数据,悄悄的消耗缓冲区的数据,这样就相当于增大了窗口的大小。然后等到合适的时机服务器在返回ACK应答。

这样使得窗口大小似乎变大了,然后效率相应的变大了。

但是也并不是所有的报都延迟。

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

八、捎带应答(效率机制)

是基于延迟应答的。
适用于:客户端,服务器,之间的通信模型,通常是“一问一答”这用模式

通信模型:

  1. 一问一答:绝大部分服务器都是这样
  2. 多问一答:上传大文件
  3. 一问多答:下载大文件
  4. 多问多答:游戏串流

原则是,客户端发送一个消息,需要等待服务器的ACK,但是因为延迟等待,数据实际上已经上传了,并且也处理好了,按照一般逻辑就是,将处理好的数据,返回给客户端,之前 ACK 还没有返回给客户端,那么此时 ACK 就会捎带着服务器处理好的数据返回给客户端。(原本分两次的返回,现在一次就可以)

九、面向字节流(粘包问题)

这个有一个巨大的问题,就是粘包问题。
根据上面的说法综合一下就知道,我们发送方传输的数据,是多个数据放在一起传输的。然后在缓冲区上集结排列,然后接收方如何将数据分离,读出一个完整的数据报,此时造成的结果就是,容易读出半个包,或者一个半的包,反正就是不是我们想要的。

如何解决?

提前约定好,数据的格式。比如:

  1. 约定结尾符号,接收方收到后,通过结尾符号知道一个完整的数据。
  2. 约定长度,约定数据的前几个字节,表示整个数据包的长度,通过光标读取字节长度。读取完整数据。

十、异常情况(心跳包)

  1. 进程关闭 / 进程崩溃
  • 进程没有了,socket是文件,随之关闭,虽然进程没有了,但是连接还在,仍然可以继续关闭连接(四次挥手)
  1. 主机关机
  • 先杀死所有的用户进程,也会触发四次挥手,如果没有挥完,比如 对方发了一个fin,咱们没来得及 ack 就关机了,姿势对端,就会重传fin ,重传几次后,发现没有 ACK ,尝试重置连接,如果还不行,就直接释放链接。
  1. 主机掉电
    主机瞬间关闭,来不及任何挥手操作。
  • 对方是发送方 :接收方收不到ACK =》超时重传 =》重置链接 =》释放链接
  • 对方是接收方:发送方,没办法立即知道,接收方死机了,这边还没有来得及发新数据,就没了。
    • TCP为了防止这种情况,内置了一个机制,心跳机制(周期性的,如果没有心跳,就代表挂了),也就是接收方会给发送方定期发一个心跳包(ping),然后发送方会给接收方发送一个返回(pong)
    • 如果每个ping都有一个pong返回,就说明接收方是好的。如果bing了很多次,还没反应,就知道就收方挂了。
  1. 网线断开
  • 同上,与主机掉电原理一样

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

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

相关文章

rocky(centos) 安装redis,并设置开机自启动

一、下载并安装 1、官网下载Redis 并安装 Download | RedisRedisYou can download the last Redis source files here. For additional options, see the Redis downloads section below.Stable (7.2)Redis 7.2 …https://redis.io/download/ 2、上传下载好的redis压缩包到 /…

k8s 搭建基于session模式的flink集群

1.flink集群搭建 不废话直接上代码,都是基于官网的,在此记录一下 Kubernetes | Apache Flink flink-configuration-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: flink-configlabels:app: flink data:flink-conf.yaml: |jobmanager…

【Vue篇】Vue 项目下载、介绍(详细版)

如何创建一个vue项目?首先要有环境,如下: nodejs vue-cli如果有以上的工具就直接跳过安装教程 【Vue篇】mac上Vue 开发环境搭建、运行Vue项目(保姆级) 创建vue项目 选择一个位置,你要存放项目的路径&…

海保人寿:开源治理保障科技与保险融合,助力保险业务数字化改革创新

海保人寿保险股份有限公司(简称“海保人寿”)是第一家在海南筹建开业的全国性保险机构。从成立之初,便深耕于数字化创新,在自身多业务环节中实现数字化转型,依托优秀的研发体系与数智融合的业务系统,不断推…

RocketMQMessageListener使用错误问题分析与排查

背景 RocketMQ与SpingBoot相结合可以大大降低我们开发的复杂度,但是最近在一个新项目中使用RocketMQMessageListener 监听消息,导致消费者启动失败,提示该消费组已经被创建了,请重新申请一个消费者组。 Caused by: org.apache.r…

【深度学习】 Python 和 NumPy 系列教程(三):Python容器:1、列表List详解(初始化、索引、切片、更新、删除、常用函数、拆包、遍历)

目录 一、前言 二、实验环境 三、Python容器(Containers) 0、容器介绍 1、列表(List) 1. 初始化 a. 创建空列表 b. 使用现有元素初始化列表 c. 使用列表生成式 d. 复制列表 2. 索引和切片 a. 索引 b. 负数索引 c. 切…

龙迅LT86102UX HDMI一进二出,支持分辨率4K60HZ

龙迅LT86102UXE 1. 描述 龙迅LT86102UX HDMI2.0 分路器具有符合 HDMI2.0/1.4 规范的 1:2 分路器、最大 6Gbps 高速数据速率、自适应均衡 RX 输入和预强调的 TX 输出,支持长电缆应用,板载无 XTAL,可节省 BOM 成本。 LT86102UX HDM…

【Linux】- Linux下搭建Java环境[IDEA,JDK8,Tomcat]

Java环境 1. 安装JDK2.安装tomcat3.安装idea4. 安装MySQL5.7 1. 安装JDK /usr/local:存放用户自行安装的软件,默认情况下不会被系统软件包管理器管理 发现解压后的文件已经整体移动到/usr/local/java 文件夹下 打开bin目录,可以看到java的版…

Nginx参数配置详细说明【全局、http块、server块、events块】【已亲测】

Nginx重点参数配置说明 本文包含Nginx参数配置说明全局块、http块、server块、events块共计30多个参数配置与解释,其中常见参数包含配置错误出现的错误日志,能让你更快的解决问题。 该文的所有参数大部分经过单独测试,错误都是自己收集出来的…

每日刷题-3

目录 一、选择题 二、编程题 1、计算糖果 2、进制转换 一、选择题 1、 解析:在C语言中,以0开头的整数常量是八进制的,而不是十进制的。所以,0123的八进制表示相当于83的十进制表示,而123的十进制表示不变。printf函数…

(翻译)JavaFX高级教程:JavaFX2.0的FXML语言

原文地址http://download.oracle.com/javafx/2.0/fxml_get_started/jfxpub-fxml_get_started.htm FXML是JavaFX 2.0新引入的。你可能会问"What is FXML?" 和"Is FXML for me?" FXML 是基于XML的一种声明性标记语言,用来定义应用的用户接口。F…

QT设计一个小闹钟

设置一个闹钟,左侧窗口显示当前时间,右侧设置时间,以及控制闹钟的开关,下方显示闹钟响时的提示语。当按启动按钮时,设置时间与闹钟提示语均不可再改变。当点击停止时,关闭闹钟并重新启用设置时间与闹钟提示…

【MySQL】详解聚合查询、多表查询

MySQL 增删查改(进阶) 文章目录 MySQL 增删查改(进阶)01 表的设计表的三大范式 02 查询操作进阶新增聚合查询countsumavgmaxmin 分组查询 GROUP BYHAVING 联合查询/多表查询关键思路引入内连接外连接左外连接:left joi…

有限状态机的概念

一、有限状态机的概念 有限状态机简称状态机,是表示有限个状态,以及在状态之间的转移和动作等行为的数学模型。状态机的要素有状态和状态转移两个。 在Unity中,动画状态机最重要的属性就是节点和连线,其中每个节点都是一个动画片…

Emscripten安装并配置环境变量

前言 Emscripten官网 官网有安装教程,但有些细节没有讲清楚,本文会很详细的讲解每一步。 一、下载 emsdk 包 emsdk – github地址 可以使用 git 去拉取,不过可能会超时拉取失败。 git clone https://github.com/emscripten-core/emsdk.…

数据结构与算法-队列

一.队列的基本概述 1.队列的定义 答:队列是现在在两端进行插入和删除操作的线性表,"队尾"是允许进行存入…

系统软件启动过程

实验一:系统软件启动过程 参考 重要文件 调用顺序 1. boot/bootasm.S | bootasm.asm(修改了名字,以便于彩色显示)a. 开启A20 16位地址线 实现 20位地址访问 芯片版本兼容通过写 键盘控制器8042 的 64h端口 与 60h端口。b.…

ApachePulsar原理解析与应用实践(学习笔记一)

随着时代的发展,软件设计的理念也在不断发展,从单体服务、面向服务、微服务,发展到云原生以及无服务。其演变的过程是一个能力不断增强,领域边界不断微分细化的过程。比如无服务就是将函数作为服务,就类似dns模式的服务…

什么是50ETF期权开户条件,怎么开期权交易权限?

50ETF期权是指上证50ETF期权,标的物是上证50ETF,代码是(510500),期权是一种在上证50ETF基础上进行衍生品交易的金融工具,下文科普什么是50ETF期权开户条件,怎么开期权交易权限?本文来…

死锁

目录 什么是死锁 产生的条件 死锁避免 银行家算法 问题引入 银行家算法的实现思想 死锁检测 每种类型一个资源的死锁检测 每种类型多个资源的死锁检测 死锁恢复 鸵鸟算法 什么是死锁 线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线…