可靠数据传输的实现

2023-11-19

可靠数据传输协议

我们知道,TCP和UDP都是基于IP网际协议来传输数据的,但是IP网际协议是一种不可靠数据传输协议,它不负责数据丢失等情况,而TCP是一种可靠数据传输,因此我们需要来关注TCP是如何实现可靠数据传输的

经完全可靠信道的可靠数据传输:rdt1.0

rdt的假设前提是我们的数据在底层信道的传输是不会出现丢失和出错的,那么我们定义一个概念

  • 有限状态机FSM: 定义了接收方和发送方的操作

可以预想到,rdt1.0的FSM肯定是很简单的,因为底层信道就实现了可靠数据传输(假设的)

rdt1.0的发送方和接收方的FSM如下:

在这里插入图片描述

经具有比特差错信道的可靠数据传输:rdt2.0

实际中在信道传输的数据是很有可能受损的,这个时候我们应当让发送方重传该分组,那么发送方如何知道是否重传一个分组呢?

  • ACK:当接收方收到一个分组时,如果该分组没有比特损伤,那么就给发送方发送一个ACK表示肯定确认,ACK可以用1比特的1表示
  • NAK:当接收方收到一个损伤的分组时,就给发送方发送一个NAK表示否定确认,NAK可以用1比特的0表示

基于这样重传机制的可靠数据传输称为自定重传请求(ABQ)协议

我们看一下rdt2.0的FSM

在这里插入图片描述
当发送方没有收到ACK或者NAK时,它是无法被上级调用的,所以rdt2.0这样的协议被称为停等协议

rdt2.0协议看起来好像是可以运行了,但是我们没有考虑到ACK和NAK出错的情况,当这两个分组出错时,发送方就无法确认发送的分组是否已经被成功接收了


rdt2.1

我们可以为ACK和NAK分组加上差错检测,这样可以解决问题

如果我们使用一个定时器,当一个分组超过时间还没收到NAK或者ACK,那么就将该分组重新发送,但是定时出现的一个问题就是,接收方并不知道这个分组是重传的还是新传的

这时候我们就可以使用序号来区分分组了,因为是分组是发送一个接收一个,所以我们只需要用序号0和1就能够区分出分组

  • 当发送方发送一个分组序号为0的分组时,它会等待一个ACK 0来确保接收方收到了分组0,如果收到了ACK0发送方接下来就发送序号为1的分组,依次循环
  • 当接收方收到一个分组序号为0的分组时,他会发送一个ACK 0分组来确认收到

我们来看rdt2.1的FSM

在这里插入图片描述

当然,我们不一定需要NAK,只要接收方发送前一个序号的ACK也能跟NAK起到同样的效果

比如说,当接收方收到序号为1的分组,但是该分组的比特受损了,因此我们需要发送方重新发送序号为1的分组,这时接收方只要发送一个ACK 0就可以了,发送方收到ACK 0就会重发序号为1的分组

基于无NAK的rdt2.2的FSM如下

在这里插入图片描述
在这里插入图片描述

rdt2.0协议是在底层信道不丢包的情况下展开的,但是底层信道是很有可能会丢包的,当出现丢包时,我们应当如何设计可靠数据传输协议

经具有比特差错的丢包信道的可靠数据传输rdt3.0

比较简单的实现方法就是为定义一个计时器,当出现超时事件时就重传该分组

rdt3.0发送方的FSM

在这里插入图片描述

rdt3.0虽然是一个正常的协议,但是它并不是很好,因为它的本质还是停等的,也就是发送一个接收一个,在确保接收之前它是不会发送其他分组的,更理想的情况是,我们希望分组是流水线的发送的,而不是停等

回退N步

回退N步(BGN)协议中,我们先定义几个量

  • base: 最早未确认分组的序号
  • nextseqnum: 最小的未使用序号

因此我们知道

[0,base-1]是已发送且确认的分组
[base,mextseqnum-1]是已发送但未确认的分组
[nextseqnum,base+N-1]待发送的分组

我们将BGN称为滑动窗口协议

也就是每当序号为base的分组收到了ACK时,就将窗口[base, nextseqnum-1]向右滑动

当base+N==nextseqnum时,表示窗口已满,上层不能再发送分组

BGN协议的FSM

在这里插入图片描述

回退N步的意思就是,当有一个分组触发超时机制,就将滑动窗口中的所有分组重传

你可能不是很理解这个有什么意义,这个的意义在于,接收方不用对接收到的分组重新排序,因为当接收方收到一个分组时,该分组前面序号的可能丢包了,如果接收方对该分组缓存,那就需要其他的协议来处理如何将其排序

因此接收方只要接收序号是已接收的下一个就可以了,如果接收到的包不是上一个递交的包的下一个,那就直接丢弃该包

因此GBN协议自然而然的就将接收到的包按序递交了

选择重传

你可能会觉得接收方将所有不按序的包都丢掉很蠢,实际上这个协议确实有缺点每丢一个包时,就要重传滑动窗口中的所有包,当滑动窗口很大时,将会导致信道中充满了冗杂的分组,因此我们引出了选择重传的概念

选择重传的实现

当接收方收到一个分组时,将其缓存起来,然后对发送方发送一个ACK(这一步是必要的,因为如果发送方没有收到这个ACK,那滑动窗口就没办法向右滑动了),当接收方收到一个序号为base的分组,就将该分组以及它后面的之前收到的连续的分组一并递交上去,同时滑动窗口

选择重传中,发送方和接收方的滑动窗口是不一样的

因为接收方虽然收到了一个失序的分组,但是它的窗口不会滑动,而发送方收到了接收方发送的ACK,则会滑动窗口,这样双方的滑动窗口就不一样,当两者的滑动窗口不一样时,会出现什么问题?

在这里插入图片描述

简单来说,就是当接收方的滑动窗口滑倒下一次序号的开始,而发送方的滑动窗口却还在前一次的序号中,那接收方就不知道接收到的分组是新传的还是重传的

因此,滑动窗口的大小应该小于等于序号空间大小的一半

参考:
《计算机网络自顶向下方法》

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

可靠数据传输的实现 的相关文章

  • LDAP协议

    1 LDAP是Lightweight Directory Access Protocol的缩写 顾名思义 它是指轻量级目录访问协议 这个主要是相对另一目录访问协议X 500而言的 LDAP略去了x 500中许多不太常用的功能 且以TCP I
  • 程序的链接

    程序的链接是一个非常实际的问题 他建立在很实际的问题之上 不从程序员的角度去思考问题 则是从软件的角度去思考如何复用错综复杂的代码 因为 这个问题的本质是我们没有给底层的硬件一个完整的可按顺序执行的程序 我们在前几章虽然讨论了指令流的问题

随机推荐

  • 【Node.js实战】一文带你开发博客项目之Koa2重构(实现session、开发路由、联调、日志)

    个人简介 个人主页 前端杂货铺 学习方向 主攻前端方向 也会涉及到服务端 个人状态 在校大学生一枚 已拿多个前端 offer 秋招 未来打算 为中国的工业软件事业效力n年 推荐学习 前端面试宝典 Vue2 Vue3 Vue2 Vue3项目实
  • QT--SQLite

    QT数据库实例 QT Sqlite操作 转载于 http mobile 51cto com symbian 273444 htm 585532 tsina 1 51851 7e393678b940a4d55500bf3feae3d2e9 S
  • 时序分解

    时序分解 MATLAB实现基于LMD局部均值分解的信号分解分量可视化 目录 时序分解 MATLAB实现基于LMD局部均值分解的信号分解分量可视化 效果一览 基本介绍 程序设计 参考资料 效果一览 基本介绍 LMD局部均值分解 直接替换Exc
  • 思维模型:建立高品质思维的30种模型

    第一章 如何快速而全面地做出决策 思维模型1 关注 重要 任务 忽略 紧急 任务 用于区分真正的优先事项和冒牌货 重要任务和紧急任务区分开 把活动和需求分类 整理出最重要的任务 并找出为了实现这些重要任务需要采取哪些最关键的流程 重要任务
  • 游戏开发unity插件CRI ADX2系列:插件下载及教程

    推荐一个比较好的声音插件 可以在较大压缩音乐资源的同时维持较好的音质 教程 https blog criware cn category tutorials https www bilibili com video av56190616 C
  • 玩转Makefile

    1 前言 Makefile是一个神奇的东西 有了它只需一个make命令就可以让源文件按你的规则编译成你所想要的程序 非常简单 方便 对于Keil VS等IDE 一般只需点一下绿色的三角按钮 就可以完成编译 但具体内部是怎么实现编译的 改动文
  • 【Spark ML】第 1 章:机器学习简介

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 解决粒子特效被NGUI遮挡的问题。

    最近给UI添加粒子特效时 总是被UI遮挡 解决方法是 因为粒子系统的渲染顺序列默认为3000 而NGUI的渲染顺序默认也是从3000开始 当有嵌套的panel时或者Depth更高的panel时 GUI的渲染顺序会高于3000 解决办法是 1
  • ValueError: PyCapsule_GetPointer called with incorrect name

    ValueError PyCapsule GetPointer called with incorrect name解决问题的方式 增高pyqt5的版本 增高pyqt5的版本 我遇到了这个问题的时候在网上查的一直是说需要降低pyqt5的版本
  • 嵌入式开发linux控制鼠标,嵌入式系统/ARM技术中的linux中如何使用微软鼠标的第4、5键...

    虽说使用linux的人大都对微软没什么好感 但不能否认微软确实也出了不少好东西呀 比如微软鼠标 IE系列 icon smile gif IE 2 0和以上版本都有5个按钮 除了正常的左中右外 两侧还各有一个 在windows中可用来支持浏览
  • 面试题之你对redis的认识

    这里是我自己看书对redis的总结 这次我们目标的Redis在java互联网项目网中的作用 在传统的javaweb项目中 使用数据库进行存储数据 但是有一些致命的弊端 主要来自性能方面 由于数据库持久化数据主要是面向磁盘 而磁盘的读 写比较
  • yarn-container的理解

    不管是MR还是spark 分布式并行计算是肯定的 分布式计算意味着多节点 每个节点必须要并行跑很多task 任务 因为如果一个节点只有一个task 那么节点数量远远不够 让开发者直接操作 cpu和内存显然不合理 要用container抽象
  • 用户在输入不符合格式要求的内容或出现多个小数点时,无法继续输入新内容,但仍然可以使用后退键进行修正

  • 美国大学生数学建模竞赛赛题特点

    美国大学生数学建模竞赛赛题特点 赛题灵活度高 内容广泛 反恐 防灾 环境 健康医疗 交通 新能源等等 开放性大 评价类问题多且复杂 离散型优化问题多 除A题 如 2016B太空碎片的处理 2018D电动车充电桩的优化 2019D卢浮宫疏散路
  • 重要通知:9月1日起,微信小程序须完成备案后才可上架

    微信官方通知 近日 工信部发布了 工业和信息化部关于开展移动互联网应用程序备案工作的通知 8月9日 微信公众平台也发布了 关于开展微信小程序备案的通知 一 备案必要性 在中华人民共和国境内从事互联网信息服务的移动互联网应用程序主办者 应当依
  • ArduCopter调试

    1 ArduPilot main 我们知道 在 C语言中最经典的程序是 Hello World 这应该是我们在 C语言中最早接触的一个程序了 而在单片机中 最经典的一个程序当属 LED了 那么这里我们为什么不去分析 Hello World
  • 使用嵌入式linux完全手册光盘的arm-linux-gcc 遇到问题 自己编译

    Redhat9下重新生成交叉编译器gcc 3 4 5 glibc 2 3 6 看到论坛上有兄弟也遇到 arm linux gcc lib tls libc so 6 version GLIBC 2 4 not found required
  • 鸿蒙手机录音,录音应用的隐藏功能,90%的人不知道?

    录音应用的隐藏功能 90 的人不知道 2019 04 22 16 57 20 1点赞 0收藏 0评论 录音应用其实隐藏着可以自动开始和结束 脱离手用蓝牙耳机录音 只在说话时录音 你使用过吗 这款录音应用可是被苹果App Store推荐过的
  • 从零开始:在腾讯云轻量服务器上安装Docker,实现快速开发和部署!

    本文指导您如何在 零基础轻量应用服务器上安装 Docker 以及使用 Docker 镜像源加速镜像下载 好了 没有废话 让我们开始行动吧 第一步 购买服务器 小编买的是 腾讯的 1年446RMB 下载链接如下 学生云服务器 学生云主机 学生
  • 可靠数据传输的实现

    可靠数据传输协议 我们知道 TCP和UDP都是基于IP网际协议来传输数据的 但是IP网际协议是一种不可靠数据传输协议 它不负责数据丢失等情况 而TCP是一种可靠数据传输 因此我们需要来关注TCP是如何实现可靠数据传输的 经完全可靠信道的可靠