计网第三章.数据链路层—可靠传输

news2024/12/22 19:37:41

以下来自湖科大计算机网络公开课的笔记

文章目录

      • 0.基本概念
      • 1. 停止等待协议SW
      • 2. 回退N帧协议GBN
      • 3. 选择重传SR

首先,这部分说的可靠传输的实现机制不只限于数据链路层,而是适用于整个计算机网络体系

0.基本概念

一般情况下,有线链路的误码率比较低,为了减小开销,并不要求数据链路层向上提供可靠传输服务,即使出现了误码,可靠传输的问题由上层处理。

无线链路易受干扰误码率比较高,因此要求数据链路层必须向上层提供可靠传输服务。

而且,数据链路层的比特差错只是传输差错中的一种,从整个计算机网络体系结构来看,传输差错还包括分组丢失、分组失序以及分组重复(注意此时不是帧”而是分组),这些都是数据链路层上层出现的,所以不仅数据链路层可选择是否提供可靠传输服务,其它各层均可选择

按TCP/IP四层协议来看:
在这里插入图片描述
上图中的网络接口层包含了数据链路层

三种可靠传输的实现机制:停止等待协议SW回退N帧协议GBN选择重传协议SR

这三种可靠传输实现机 制的基本原理并不仅限于数据链路层,可以应用到计算机网络体系结构的各层协议中

所以后面介绍三种机制的时候,不是在点对点这种链路上,而是跨越整个互联网的两个主机之间

1. 停止等待协议SW

SW(Stop-and-Wait)

确认分组:简称ACK

1.1 否认分组
发送方发送数据,只有在收到接收方对所发送数据的确认分组ACK后才能继续发送下一个分组;如果这个分组发送后出现误码(接收方进行了差错检测),接收方则丢弃该分组并给发送方发送否认分组,简称NAK,发送方收到NAK之后就会重传该数据——这说明发送方在发送完一个数据分组后并不能立刻将该数据分组从缓存中删除,因为可能要重传,只有收到了确认分组ACK之后才会将其从缓存中删除。
在这里插入图片描述
注意上图中发送方和接收方之间是整个互联网!而不仅仅是数据链路层

1.2 超时重传

如果一开始发送方的数据就没发到接收方那呢(对数据链路层点对点信道而言不太容易出现这种情况,但是对于多个网络多个路由器互连的互联网环境而言却经常出现)。这个时候接收方也不会发送ACK或者NAK。

那发送方岂不是会一直处于等待状态?

所以需要超时重传机制:在发送方发送完一个数据分组时,启动一个超时计时器,若到了超时计时器所设置的重传时间而发送方仍收不到接收方的任何ACK或者NAK,则重传原来的数据分组,这就叫超时重传

一般将重传时间选为略大于“从发送方到接收方的平均往返时间”。
在这里插入图片描述
1.3 数据分组编号

既然数据DATA都可能丢失,那接收方发送的ACK或NAK也可能丢失

当发送方一直没等到ACK或NAK,就触发超时重传,又发了一遍DATA,这样分组就重复了。那接收方如何判断该数据分组是重复的呢。

所以要给每个数据分组带上序号

对于停止—等待协议,由于每发送一个数据分组就停止等待,只要保证每发送一个新的数据分组,其发送序号与上次发送的数据分组的序号不同就可以了,这样用一个比特来编号就够了

像前面说的,发了一个DATA分组,编号为0,一直没收到ACK或NAK,那超时重传再发这个分组,编号还是0,因为是同一个分组,当终于收到ACK时,就开始1发送新的分组了,这个时候编号就是1…后面依次01交替,只要是新的分组数据,那编号就得和前面不一样,过程如图:
在这里插入图片描述
1.4 确认分组编号

如果仅仅是数据分组有编号,当DATA0发完后,接收方收到了并发送ACK,但由于某些原因,ACK迟到了,那发送方就会启动超时重传机制,再发送一下DATA0,在传输0号数据分组过程中发送方收到了前面迟到的ACK,那就会发一下新的数据分组DATA1。

接收方先收到DATA0,再收到DATA1,在收到DATA0的时候就会发送ACK,发送方收到ACK后会误以为是对DATA1的确认:
在这里插入图片描述
所以要区分开的话,ACK也得编号。如下图所示,对DATA0的确认分组ACK编号为0,对DATA1的ACK编号为1,这样就解决了确认迟到问题:
在这里插入图片描述

当然,对于数据链路层的点对点信道,往返时间比较固定,不会出现确认迟到的情况,所以如果只在数据链路层实现停止—等待协议,可以不用给确认分组ACK编号

小结与补充:

  • 接收方要是收到误码率较高的数据分组,也可以丢弃后等待发送方超时重传,发送NAK分组是为了尽早重传

  • 数据链路层一般不会出现ACK分组迟到的情况,因此数据链路层实现停止—等待协议时,可以不用给确认分组ACK编号

  • 超时计时器的重传时间应该仔细选择,一般是略大于从发送方到接收方的平均往返时间,数据链路层点对点往返时间比较确定,好设置,但是在传输层,端到端往返时间非常不确定,设置合适重传时间并不容易

停止—等待协议的信道利用率,如图:

TD是发送方发送数据分组所耗费的发送时延;RTT是收发双方之间的往返时间;TA是接收方发送确认分组所耗费的发送时延。图中忽略了接收方对数据分组的处理时延和发送方对确认分组的处理时延。

TA远小于TD,一般可以忽略,当RTT远大于TD时,信道利用率会非常低(很好理解,把分组送到传输线路上要等很久才能传到那边,然后才能开始传下一个分组,这个时间已经很多分组分好了,排队等着被传送呢)
在这里插入图片描述

前面提到过:源主机将分组发往传输线路,需要花费一定时间,这段时间称为发送时延

1.5 停止—等待协议的局限性:

  • 当往返时延RTT远大于数据帧发送时延TD时(例如使用卫星链路),信道利用率非常低。

  • 若出现重传,则对于传送有用的数据信息来说,信道利用率还要降低

为了克服停止—等待协议信道利用率低的缺点,就产生了另外两种协议,即后退N帧协议GBN和选择重传协议SR

习题:

可以看到这里就忽略了接收方发送确认分组所耗费的发送时延TA:
在这里插入图片描述

流水线传输:
前面说到停止—等待协议SW的信道利用率低,如果发送方在收到接收方的确认分组ACK之前,可以连续发送多个数据分组,则可大大提高信道利用率,如图:
在这里插入图片描述
图中,上面是停止等待协议,下面就是流水线传输,可以提高信道利用率

2. 回退N帧协议GBN

回退N帧协议就是在流水线传输基础上,再加一个窗口限制

假设我们用3个比特给各个分组编号,000,001,010…这样能标到111,也就是十进制的0~7

发送方窗口的尺寸WT的取值就是(1, 7],不取1,因为窗口尺寸为1时就是停止等待协议了,不取8的原因看后面

接收方窗口和停止等待协议一样,也是1,如下图:

接收窗口大小为1是为了依次确认分组号,而且大于1一样的处理时间,发送方那边还是等那么久

在这里插入图片描述
2.1 无差错传输情况
在这里插入图片描述
传输过程没有出现乱序或误码时

因为接收方那边也有分组序号,和发送方的一样,那边依次接收0,1,2,3,4,可以不用每接收一次就发送ACK,可以等收到几个分组,如收到5个,再一块发,而且不是发5个,是发最后那个的分组确认即可——这就是累积确认
在这里插入图片描述
发送方收到ACKn后就知道前面n个已经全部发到对面了,然后滑动窗口到n后面,并把前面的分组从缓存中删除

如果接收方那边收到0,1两个分组,就发送以下ACK1,然后收到分组2,3,4就发送以下ACK4,传输过程中ACK1丢了,发送方只收到ACK4,也是正常滑动窗口

这是累积确认的一个**优点:**即使确认分组丢失,发送方也可能不必确认重传

还可减小接收方的开销,减少对网络资源的占用。

缺点:不能及时向发送方反映出接收方已经正确接收的分组信息。

2.2 出现差错情况

滑动窗口往右滑,依次发送5,6,7,0,1
在这里插入图片描述
其中,5号分组出现误码,接收方丢弃5号而后面的6,7,0,1又和接收方的接收窗口号5不匹配,所以也一块丢弃了

然后对之前正确按序接收的最后一个数据分组进行确认,即发送ACK4,每丢弃一个数据分组就发送一个ACK4

发送方收到重复的确认,就知道之前的数据分组出现了差错,于是不等超时计时器,立刻重传——至于收到几个重复确认就重传,由具体实现决定

回退N帧的由来

在本例中,虽然序号为6,7,0,1的数据分组正确到达接收方,但由于5号数据分组误码不被接受,它们也受到“牵连”而不被接受,发送方还要重传这些数据分组,这就是所谓的Go-back-N(回退N帧)

可见,当通信线路质量不好时,回退N帧协议的信道利用率并不比停止—等待协议高

2.3 滑动窗口超过分组编号的取值上限

假设窗口是8个,如果现在窗口内8个分组依次是0,1,2,3,4,5,6,7(同一个窗口内各分组号肯定得不一样,编号就是为了区分不同分组,编号一样那就区分不开了,而且编号都是对数据分组依次编的)

然后发到接收方,接收方收完了,接收窗口移到下一位0,然后发送最后一个编号的分组确认ACK7,结果ACK7在路上丢失了,发送方那边一直没收到就开始超时重传,又是依次发送0,1,2,3,4,5,6,7,又是0,符合接收窗口内的分组号,那接收方又接受原来的数据了!
在这里插入图片描述
回退N帧协议的总结:
在这里插入图片描述
补充,发送方是收到一个ACKn就滑动位置,比如收到ACK2,滑动窗口就滑动到2的后面,即3开始
在这里插入图片描述
其中ACK1丢失的话,此时窗口是不滑动的,因为没收到ACK

3. 选择重传SR

回退N帧协议的接收窗口尺寸WR只能等于1,因此接收方只能按序接收正确到达的数据分组;

一个数据分组的误码就会导致后续多个数据分组不能被接收,尽管后面的分组没有误码,这些也需要重传,浪费通信资源;

为了提高性能,可设法只重传出现误码的数据分组,因此接收窗口的WR不应再等于1(而应再大于1),以便接收方先收下失序到达但无误码并且序号落在接收窗口内的那些数据分组,等到所缺分组收齐后再一并送交上层。这就是选择重传协议

注意:

选择重传协议为使发送双方仅重传出现差错的分组,接收方不能再采用累积确认,而需要对每个正确收到的数据分组进行逐一确认

如下图中,接收方的接收窗口WR = 4:
在这里插入图片描述
图中示例是数据分组2出现误码,接收方只发送了ACK0,ACK1,ACK3,并且接收方窗口只右移两个因为2没收到,还得在窗口内,发送方也是,收到ACK0,ACK1就可以右移两个(这里就体现出是一个一个分组编号确认的,而之前回退N帧协议只看最后一个ACKn),右移两个,发送4和5,收到ACK3后标记3已经传完了,然后接收方那边收到了4和5也发送ACK4,ACK5,这期间发送方的超时重传机制可能触发了,所以重新发送数据分组2。

等接收方收到数据分组2之后,窗口内的数据全收完了,就可以往后移动:
在这里插入图片描述
当ACK2也发到了发送方那里的时候,发送方窗口也可以右移了:
在这里插入图片描述
收发窗口尺寸:
在这里插入图片描述
发送窗口不能比2的n-1次方大,比如n = 3用三个比特记录时,总共能编8个不同分组,此时发送方窗口最多只能是7不能是8,更不能超过,总共前面讲过。

同时,接收窗口的尺寸要小于等于发送窗口尺寸,否则没有意义——如果更大的话,那发送方永远不能收到最后一个ACK,两边的窗口都没法往下滑动

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

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

相关文章

Docker 中的挂载卷

我们现在有这样一个需求。 我们有一个 Spring 的项目是部署在容器中的,如果不进行任何配置的话,这个项目运行的所有日子都会在容器中。 当容器重启说着终止后,上面的日志比较难进行查看。 我们希望我们的日志同时也记录在操作系统中&#…

阿贡国家实验室:量子中继器及其在量子网络中的作用

很多人小时候都玩过传声筒游戏:A将消息小声告诉B,然后B将他听到的内容小声告诉C,依此类推,玩过的人都知道,最后传达到的信息往往和真实消息完全不同。 从某种意义上说,这和中继器技术的重要性强相关。中继器…

MySQL锁,锁的到底是什么?

只要学计算机,「锁」永远是一个绕不过的话题。MySQL锁也是一样。 一句话解释MySQL锁: MySQL锁是解决资源竞争的一种方案。 短短一句话却包含了3点值得我们注意的事情: 对什么资源进行竞争?竞争的方式(或者说情形&a…

舆情监控和应急处理方案,如何做好网络舆情监控?

舆情监控是指通过不同的渠道,如社交媒体、新闻媒体、博客、论坛等,对公众的言论进行收集、分析、评估和反馈的过程。舆情监控的目的是帮助企业或组织了解公众的观点和情绪,并且能够及时做出回应,避免可能出现的舆论危机。接下来TO…

2022年度投影仪行业数据分析报告:十大热门品牌排行榜

在当前的大环境下,线下娱乐受阻,而用户对于足不出户的观影、娱乐需求推动着智能投影设备的增长。近几年来,投影仪行业保持着较快速度的增长,面对整体市场需求不振的形势,投影仪仍在保持正向增长。随着家用智能投影在市…

Charles - 阻塞请求、修改请求与响应内容、重定向请求地址、指定文件为响应内容

1、阻塞请求 1、鼠标放在指定接口上 > 右键 > 勾选 Block List 2、重新访问这接口,这条请求被阻塞,不会有返回信息 取消阻塞接口: 鼠标放在指定接口上 > 右键 > 取消勾选 Block List 2、修改请求与响应内容 第一步&#xff1…

【一文看懂 ES 核心】存储查询集群

一文看懂 ES 核心 Elasticsearch 作为一个搜索引擎,其可以提供高效的搜索匹配数据的能力,对于这类工具了解其运行原理其实是有一套功法的。 聊存储,ES 是如何存储数据的?聊方法,ES 是如何进行搜索匹配的?…

【Linux】文件描述符、文件操作、重定向的模拟实习

目录 一、重温C语言文件操作 1.1 文件打开方式 1.2 文件写操作 1.3 文件读操作 1.3 标准输入输出 二、系统接口的使用 2.1 open 函数 2.2 close 函数 2.3 write 函数 2.4 read 函数 三、文件描述符 3.1 如何管理文件 3.2 0 & 1 & 2 3.3 文件描述符的分配…

种草!超好用的PDF转换器上线啦~

宝子们 重磅福利来啦 你还在为每次转换文件头疼吗 老铁,大拿版万能转换器正式上线啦 以前的文件转换器,不是充会员就是收费高 最坑的是花钱还解决不了问题 每次转换文件内容有误.... 特殊符号或者公式更是无法有效转换 为了整顿这种局面&#xff0c…

KKT条件理解

我们知道拉格朗日函数是用于等式约束的优化问题求解的,然KKT条件是针对含有不等式约束的优化问题的。 首先,我们先给出优化目标: 因此,根据优化目标,我们同样可以构造处拉格朗日函数,并对其进行优化&#…

ssh免密登录

准备两台linux主机 主机A:192.168.92.131 主机B:192.168.92.132 使用主机B去免密访问主机A 在主机B上执行 ssh-keygen -t rsa ssh-keygen 生成密码对 -t rsa 指定生成 rsa 密钥对 密钥对文件默认放在 家目录下面的 .ssh 目录下 root 用户默认放在 /ro…

一、数据库开发与实战专栏导学及数据库基础概念入门

文章目录一、专栏导学1.1 课程内容1.2 学习安排1.3 适合人群1.4 学习方法二、认识数据库2.1 生活中的数据库2.2 数据管理技术的3个发展阶段2.3 数据库、关系型数据库、非关系型数据库概念2.4 为什么要使用数据库2.5 数据库系统及其组成部分2.6 常用数据库访问接口简介2.7 数据库…

【2】Go语言的语法

一、Go语言基础组成 Go语言基础组成: 包申明引入包函数变量语句&表达式注释实例: package main //申明包 import "fmt" /* 这是一个朴实无华的注释 */ func main() { fmt.Printf("mogu") } 实现流程: 第一行&#…

kafka简介

目录 partition和consumer group offset的管理 kafka的事务 幂等producer 事务producer 怎么理解trasactional.id 两阶段2pc简介 kafka的消息传输保证 producer端 broker端 consumer端 消息挤压 kafak的存储 kafka的高性能 附录-kafka demo kafaka的发布-订阅模…

Rust之常用集合(三):哈希映射(Hash Map)

开发环境 Windows 10Rust 1.66.0VS Code 1.74.2项目工程 这里继续沿用上次工程rust-demo 在哈希图中存储带有关联值的键 我们常见的集合中的最后一个是哈希映射。HashMap<K, V>类型使用散列函数存储K类型的键到V类型的值的映射&#xff0c;这决定了它如何将这些键和值…

Vue2.0

JavaScript&#xff08;JS 教程&#xff09; - JavaScript | MDN Vue是构建用户界面的 JavaScript 框架 安装 — 2.0 Vue.jsGitHub - vuejs/devtools: ⚙️ Browser devtools extension for debugging Vue.js applications.Installation | Vue DevtoolsVSCode插件&#xff1a…

【SpringMVC】SpringMVC整合Mybatis

1.整合思路 第一步&#xff1a;整合dao层 mybatis和spring整合&#xff0c;通过spring管理mapper接口使用mapper的扫描自动扫描mapper接口在spring中进行注册 第二步&#xff1a;整合service层 通过spring管理service接口使用配置方式将service接口配置在spring配置文件中实现…

如何能有兴趣的编代码,而不是畏难?

如果我告诉你&#xff0c;成功做出一道代码题拿下5万美元&#xff0c;做出四道代码题20万美金的年薪到手&#xff0c;你是不是会立刻发愤图强呢&#xff1f;这不是个段子&#xff0c;是北美程序员的面试情况&#xff1a;有小伙伴刷题的过程中觉得刷不下去了&#xff0c;就以此来…

【Javassist】快速入门系列10 当检测到instanceof表达式时用代码块替换

系列文章目录 01 在方法体的开头或结尾插入代码 02 使用Javassist实现方法执行时间统计 03 使用Javassist实现方法异常处理 04 使用Javassist更改整个方法体 05 当有指定方法调用时替换方法调用的内容 06 当有构造方法调用时替换方法调用的内容 07 当检测到字段被访问时使用语…

Android核心技术——Jetpack Hilt依赖注入

依赖注入是什么 个人理解&#xff1a;把有依赖关系的类放在容器中&#xff0c;解析这些类的实例&#xff0c;并在运行时注入到对应的字段中&#xff0c;就是依赖注入&#xff0c;目的是为了类的解耦 例子&#xff1a;A 类 中用到了 B 类&#xff0c;一般情况下需要在 A 类中 …