哈工大计算机网络传输层协议详解之:可靠数据传输的基本原理

news2024/11/16 17:30:21

哈工大计算机网络传输层协议详解之:可靠数据传输的基本原理

可靠数据传输原理

什么是可靠?

  • 不错、不丢、不乱

    可靠数据传输协议

  • 可靠数据传输对应用层、传输层、链路层都很重要

  • 网络Top-10问题

  • 信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性

在这里插入图片描述

可靠数据传输可以从不同的角度来看,比如从a图是从提供的服务来看:

红线网上是应用层,在发送方是一个发送的进程,接收方是一个接收的进程。红线下面的传输层为上层提供可靠的数据传输服务,虽然从底层来看仍然是不可靠的信道,但是传输层通过设计的策略来实现可靠。

进一步的,从服务的实现角度(b图)来看,由于底层仍然是一个不可靠的信道,可靠数据的实现要在传输层借助算法实现,包括了发送方的可靠数据传输协议部分和接收方可靠数据传输协议部分。这两部分相互配合,共同实现可靠的数据传输协议。

因为下层仍然是不可靠的信道,因此传输层向下调用的是udt_send方法,即unreliable data send,发送到信道中。而此时传输层对上层来看是一个可靠的传输协议,因此上层调用的是rdt_send,即reliable data send。

总而言之,这就相当于在传输层实现了一套可靠传输协议,并对上层透明,对上层应用来说它所面向的就是可靠数据传输,尽管底层的信道仍然是不可靠的,也就是a图中从服务角度来看。

在这里插入图片描述

从图中可以看到,在传输层和不可靠信道(比如网络层)之间是双向的箭头,也就是说在不可靠信道上实现可靠的数据传输,并不是一个简单的单向数据流动就能实现,需要双向的控制消息的流动。

可靠数据传输协议

只考虑单向数据传输,但是控制信息双向流动。利用状态机(Finite State Machine, FSM)刻画传输协议

接下来,我们从易到难,逐步递进来分析一下实现可靠数据传输的方案和流程。

Rdt 2.0:产生位错误的信道

首先我们假定一个简单的场景,即信道只会产生位错误,而不会有其他错误产生。

**场景:**传输中可能会发生位错误,比如把某个0翻转为1,把某个1翻转为0。目前的场景认为信道只可能发生这种错误,不会发生分组丢失等其他问题,并且数据是按顺序到达的。这种场景下来研究位错误时,可靠传输机制如何来实现。

接收方:

  • 需要知道接收的数据是否发生了位错误
  • 如果发生了错误,需要发送方重传
  • 需要告诉发送方出现错误,需要恢复数据

接收方如何判断接收的数据是否发生了位错误?

利用校验和检测位错误

如何从错误中恢复?

  • 确认机制(Acknowledgements, ACK):接收方显示地告知发送方分组已正确接收
  • NAK:接收方显示地告知发送方分组有错误
  • 发送方收到NAK后,重传分组

接收方显示的反馈给发送方一些控制消息:ACK/NAK

基于上述这种重传机制的rdt协议被称为ARQ(Automatic Repeat reQuest)协议

基于上述思想,设计如下的有限状态机:

在这里插入图片描述

发送方有限状态机

此时,发送方存在两个有限状态:Wait for call from aboveWait for ACK or NAK

  • 第一个状态表示等待上层调用,比如应用层向传输层发送数据(rdt_send),接收到数据后会调用make_pkt进行打包,此时会携带是数据的checksum校验和,最后调用udt_send发送到接收方。

  • 第二个状态表示等待ACK/NAK控制状态的返回,即停—等协议。

上述发送方的有限状态机即表示:接收上层协议的调用,并将数据打包发送到接收方,同时,停止等待接收方ACK/NAK状态信息的返回。如果接收到的是NAK状态,则重新执行udt_send将数据重传到接收端。如果接收到的是ACK状态,则回到第一个状态,等待下次调用。

接收方有限状态机

  • 只有一个状态,表示等待下层协议的调用。此时会去判断接收的数据是否有错误。如果有错误,则调用udt_send方法返回NAK状态,如果没有错误,则返回ACK状态。

Rdt 2.1:发送方。应对ACK/NAK破坏

Rdt2.0有什么缺陷?

如果ACK/NAK消息发生错误/被破坏(corrupted)会怎么样?

  • 为ACK/NAK增加校验和,检错并纠错
  • 发送方收到被破坏ACK/NAK时不知道接收方发生了什么,添加额外的控制消息
  • 如果ACK/NAK坏掉,发送方重传
  • 不能简单的重传:产生重复分组。比如前一个分组已经被接收端正确接收了,但是返回的ACK/NAK坏掉了,导致发送方重传,此时就会产生重复分组。

如何解决重复分组问题?

  • 序列号(Sequence number):发送方给每个分组增加序列号
  • 接收方丢弃重复分组

发送方有限状态机

此时发送方的有限状态机设计如下所示:

在这里插入图片描述

假设这里使用两个序列号,0和1,可以看到状态机的状态翻倍了,因为要停止等待不同序列号下数据的ACK/NAK。这里在make_pkt方法中携带了每个数据包对应的序号,此时对于上述重传可能产生分组重复的问题,相同序号的数据包会在接收到被丢弃。

接收方有限状态机

在这里插入图片描述

可以看到有限状态机的状态也翻倍了,分别等待接收序号为0和1的数据包。

Rdt2.1 vs Rdt2.0

发送方

  • 为每个分组增加了序列号
  • 两个序列号就够用,为什么?
  • 需校验ACK/NAK消息是否发生错误
  • 状态数量翻倍
    • 状态必须记住当前的分组序列号

接收方

  • 需判断分组是否重复
    • 当前所处状态提供了期望收到分组的序列号
  • 注意:接收方无法知道ACK/NAK是否被发送方正确收到

Rdt 2.2:无NAK消息协议

实际上,我们并不需要两种状态来表示接收方是否正确接收数据。

与rdt2.1功能相同,但是只使用ACK,如何实现?

  • 接收方通过ACK告知最后一个被正确接收的分组
  • 在ACK消息中显式地加入被确认分组的序列号
  • 发送方收到重复的ACK之后,采取与收到NAK消息相同的动作,重传当前分组。

Rdt2.2 状态机片段

在这里插入图片描述

Rdt3.0:如果信道既可能发生错误,也可能丢失分组,怎么办?

”校验和 + 序列号 + ACK + 重传”够用吗?

如果发送方发送的一个数据分组在信道中丢失了,此时发送方和接收方分别会采取什么反应?

此时,接收方没有收到数据,则什么也不做,仍然一直等待接收数据。而发送方则会一直等待接收方反馈的状态信息(状态机停留在Wait for ACK状态)。在这种情况下,这个分组就完全丢失了,变成不可靠传输了。

又或者,数据分组到达接收方,但是接收方返回的ACK在信道中丢失了,此时发送方也会一直等待下去,此时这个协议就不能正常工作了,也就是上面的Rdt2.2的机制就不够用了

怎么解决上述问题?

解决方案也很简单:超时重传。

即发送方等待“合理”的时间,如果超时没收到ACK,则重传。

同时,由于存在分组或ACK只是延迟而不是丢失,导致的超时后,数据重复的问题,仍然采用上述Rdt2.1机制中介绍的序列号的方法:

  • 发送端发送数据时加上序列号,接收方对于重复的序列号遗弃。
  • 接收方返回ACK时,需要在ACK中显式的告知所确认的分组序号

Rdt3.0有限状态机图例:

在这里插入图片描述

从上图中可以看出:

  • 在接收到上层的数据后,发送端除了将数据包发送出去外,还会启动一个定时器(start_timer),然后进入等待ACK的状态。
  • 这里Wait for ACK状态中,多了一种状态转移条件,即timeout。如果timeout超时,则触发udt_send重传数据。

Rdt3.0工作的几种场景

在这里插入图片描述

右图的timeout即显示了当丢失了packet时,等待超时时间后,发送方重传packet,此时当数据包丢失时,rdt3.0仍能正常工作。

在这里插入图片描述

C图表示了当接收方返回的ACK1丢失时,发送方再等待timeout时间后,对数据包进行了重传。此时,由于接收方会接收到两个pkt1,即重复的packet,由于有序号机制,接收方发现存在两个相同序列号的数据包,会丢弃刚刚收到的这个pkt1的数据包,并重发ACK1。在这种场景下,即使ACK丢失了,rdt3.0机制仍能正常工作。

D图表示了ACK没有丢失,只是延迟到达的场景。此时,发送端在等待timeout时间后对pkt1数据包进行了重传,然而此时发送方才收到ACK1的返回。这种情况接收方也会出现接收到重复分组的问题,但是由于存在序列号机制,接收方仍然可以根据序列号丢掉重复的分组。而发送方也会接收到两个重复的ACK1的返回,根据上图中发送方的有限状态机状态可以发现,由于在前一个ACK1到达后,发送端就发送pkt0的数据了,因此停留在等待ACK0响应的状态,因此第二个ACK1不会引起状态机的状态转移,相当于也会被接收方丢弃。(因为是示例,所有图中只有两个状态,实际上TCP在解决这个问题时,会丢弃返回的ACK序号小于当前发送数据包序号的ACK)。因此这种场景下,即使ACK重复,rdt3.0机制仍能正常工作。

到此我们的rdt3.0机制中解决了之前多个场景下的问题,引入了序号机制、超时重传机制等。

Rdt3.0性能分析

Rdt3.0能够正确工作,但相对来说性能很差,特别是当带宽速率很高的时候

示例:比如存在一个1Gbps的链路,由于链路比较长,存在15ms端到端的传播延迟,假定发送的每个分组大小是1KB

则此时的分组的在该链路上的传输时间为:

在这里插入图片描述

即需要8s,可以将一个分组从这个链路上发送出去。由于rdt3.0是一个停等协议,因此发送完数据分组后,会停止等待ACK的返回。

由于端到端的传播延迟为15ms,因此rtt约等于30ms(一个来回)。

发送方利用率:发送方发送时间百分比:

在这里插入图片描述

相当于在1Gbps链路上,每30ms才发送一个分组 -> 33KB/sec

网络协议限制了物理资源的利用

在这里插入图片描述

rdt3.0导致的性能较差的原因,本质上就是因为停止等待协议。

总结

上面我们通过自己设计可靠传输协议的方式,来层层递进地展示可靠性传输算法所要解决的问题和实现原理。更进一步的,借助于有限状态机的状态更新来标识可靠性传输步骤,其中如果能吃透有效状态机在可靠性传输过程中的状态转换,会很有助于我们自己理解可靠性传输的机制和原理。

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

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

相关文章

【最全】如何不写代码将 Dicom 图像转 Nifti 格式, 7种工具任你选!

大多数医学成像设备以复杂的 DICOM 格式(后缀 .dcm)的变体存储图像。许多科学工具希望医学图像以更简单的 NIfTI 格式(后缀 nii.gz)存储。事实上,我们做深度学习基本都是使用的 nii.gz 格式或者 nii 格式。 那么,如何将 dicom 格…

一文吃透 CSS Flex 布局

原文链接:一文吃透 CSS Flex 布局 教学游戏 这里有两个小游戏,可用来练习 flex 布局。 塔防游戏 送小青蛙回家 Flexbox 概述 Flexbox 布局也叫 Flex 布局,弹性盒子布局。 它决定了元素如何在页面上排列,使它们能在不同的屏幕…

Mysql索引、事务以及存储引擎

目录 一、索引 1.概述 2.作用 3.索引的缺点 4.创建索引的原则依据 5.索引分类和创建 5.1普通索引 5.2唯一索引 5.3主键索引 5.4组合索引(单列索引与多列索引) 5.5全文索引(FULLTEXT) 6.查看索引 7.删除索引 二、事务…

测试必会技能之接口性能测试方案你会不会写?

目录 一、 性能测试术语解释 二、 性能测试方法及目标 三、 性能需求分析 四、 性能测试范围 五、 并发数计算方法 六、 性能测试用例与场景 七、 性能测试工具选择 八、 性能测试结果分析 九、 性能测试通过标准 总结: 一、 性能测试术语解释 …

腾讯云服务器可用区什么意思?

腾讯云服务器可用区什么意思?可用区(Zone)是指腾讯云在同一地域内电力和网络互相独立的物理数据中心,一个可用区故障不会影响另一个可用区的正常运行,所以可用区用于构建高容灾、高可靠性应用。腾讯云服务器网来详细说…

java为什么不支持多继承

Java为什么不支持多继承 前面我们提到过“继承则好比武侠中的传承血脉,子类可以继承父类的属性和方法,并且可以根据需要进行自我扩展,这样就不用从头造轮子,提高了代码的重用性和可维护性。”,在java中支持接口实现多继…

龙芯电脑(LoongArch)如何升级BIOS(UEFI固件)

龙芯UEFI 获取地址(包括3A5000 台式机,笔记本,3C5000 服务器): gitee: https://gitee.com/loongson/Firmware github: https://github.com/loongson/Firmware 根据自身机型选择相应的固件(Image目录有相…

第七章——微分方程

注://之后的都是注释,不是过程。 一、求常系数线性齐次微分方程的通解 1.一般形式:ypyqy0。 2.齐次:“齐次”的含义就是次数相等,ypyqy0都是一次幂,所以是齐次线性微分方程,如果说加上一个常…

有理函数积分

有理函数积分,一共分为三步: ①有理函数拆分 ②求待定系数 ③积分 一、有理函数拆分 有理函数拆分就是需要把被积函数拆开成若干项简单真分式相加。 (真分式:分子最高次幂<分母最高次幂) 简单真分式&#x…

自定义注解实现数据脱敏

自定义注解实现数据脱敏 在实际开发中经常会遇到有一些信息不能全部展示用户,需要隐藏(可以叫脱敏)一部分的情况比如地址,电话,手机号,身份证等。 脱敏的做法目前我知道的方法有: 1)…

JMeter 性能测试基本过程及示例,希望可以帮到你

目录 jmeter 为性能测试提供了一下特色: 基本过程 总结 jmeter 为性能测试提供了一下特色: jmeter 可以对测试静态资源(例如 js、html 等)以及动态资源(例如 php、jsp、ajax 等等)进行性能测试 jmeter 可…

(CVPR-2014)DeepPose:通过深度神经网络进行人体姿态估计

DeepPose:通过深度神经网络进行人体姿态估计 论文题目:DeepPose: Human Pose Estimation via Deep Neural Networks 论文是谷歌发表在CVPR 2014的工作 论文地址 Abstract 我们提出了一种基于深度神经网络 (DNN) 的人体姿态估计方法。姿势估计被表述为基…

202318读书笔记|《芭蕉·芜村·一茶:俳句三圣新译300》——樱花——让一整个春夜亮起来!

202318读书笔记|《芭蕉芜村一茶:俳句三圣新译300》——樱花——让一整个春夜亮起来! 《芭蕉芜村一茶:俳句三圣新译300》诗歌,词,短歌,俳句我都喜欢,读起来轻松明快! 松尾…

【代码实验】YOLO V7利用pycocotools进行评估时的一些问题

文章目录 一、无法使用pycocotools进行评估二、使用pycocotools计算的结果与YOLO自身的mAP差异较大的原因 一、无法使用pycocotools进行评估 yolov7有自己的计算mAP方式,但是在使用pycocotools进行test时,出现了pycocotools unable to run: Results do …

Java关键词synchronized

目录 一、通过卖票系统观察多线程的安全隐患 二、synchronized的基本知识 1.使用synchronized的原因 2.synchronized的作用 3.synchronized的基本格式 a.synchronized加在方法名前 b.synchronized用在方法中 4. Java锁机制 5.synchronized注意事项 三、使用synchronize…

【可变参数列表如何可变?】

可变参数列表 本章重点 学会使用可变参数列表的使用与原理 函数传参补充知识 如果函数没有形式参数,仍然可以给函数传递参数。在c语言中,只要发生了函数调用并且传递了函数,必定形成临时变量。所谓的临时拷贝本质就是在栈帧内部形成的&#…

Tcl常用命令备忘录-基础篇

一、置换 1、变量置换 在Tcl中,$符号可以用来引用变量。变量置换可以用来将变量的值嵌入到代码中。例如: set name "Tom" puts "Hello, $name!"这个示例中,变量$name的值会在输出语句中被替换为"Tom"。 2…

腾讯云服务器镜像市场快速搭建WordPress博客网站教程

通过腾讯云服务器的镜像市场搭建WordPress网站非常简单,不需要手动配置WP所需的Web环境,一键即可安装WordPress博客,腾讯云百科使用腾讯云服务器通过镜像市场的WordPress镜像搭建WP网站教程: 目录 腾讯云服务器通过市场镜像安装…

SpringMvc拦截器和手写模拟SpringMvc工作流程源码详解

目录 1. SpringMvc简介 1.1 什么是MVC 1.2 什么是SpringMvc 1.3 SpringMvc 能干什么 1.4 SpringMvc 工作流程 2. SpringMvc拦截器和过滤器 2.1 拦截器 2.1.1 拦截器作用 2.1.2 拦截器和过滤器的区别 2.1.3 拦截器方法说明 2.1.4 多个拦截器执行顺序 2.1.5 自定义拦…

29 虚拟地址到物理地址的转换

前言 呵呵 这是 linux 中内存管理中很基础的一环 用户程序 操作的地址都是虚拟地址, 虚拟地址通过 mmu 转换为物理地址 用户程序 看到的地址都是一个完整的世界, 只有具体需要使用的时候 产生缺页中断, 然后 分配具体的物理页 这里 要说的就是 虚拟地址 到 物理地址 的转…