计算机网络超详细笔记(三):数据链路层
前言
如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。
文章目录
- 前言
- 第三章 数据链路层
- 3.1 数据链路层概述
- 3.1.1 数据链路层功能与帧
- 3.1.2 字符计数法 (不用)
- 3.1.3 字节填充的标志字节法 (常用)
- 3.1.4 比特填充的标志比特法 (常用)
- 3.1.5 物理层编码违例法
- 3.1.6 课程总结
- 3.2 差错处理概述
- 3.2.1 差错处理概述
- 3.2.2 海明距离
- 3.2.3 课程总结
- 3.3 纠 1 位错的海明码
- 3.3.1 数据位与冗余位
- 3.3.2 海明纠错码
- 3.3.3 课程总结
- 3.4 检错码
- 3.4.1 奇偶校验码
- 3.4.2 互联网校验和
- 3.4.3 循环冗余校验码 (CRC)
- 3.4.4 课程总结
- 3.5 基本数据链路协议 (1-3)
- 3.5.1 前提假设
- 3.5.2 无限制的单工协议 (协议 1 )
- 3.5.3 单工停-等协议 (协议 2 )
- 3.5.4 有噪声信道的单工协议 (协议 3 )
- 3.5.5 课程总结
- 3.6 滑动窗口协议 (协议4)
- 3.6.1 滑动窗口基本概念
- 3.6.2 窗口大小为1的滑动窗口协议
- 3.6.3 协议 4 的信道利用率
- 3.6.4 课程总结
- 3.7 回退n帧与选择性重传(协议5、6)
- 3.7.1 批量发送面临的问题
- 3.7.2 回退n帧 (协议5)
- 3.7.3 选择性重传 (协议6)
- 3.7.4 三个滑动窗口协议窗口大小
- 3.7.5 课程总结
第三章 数据链路层
3.1 数据链路层概述
3.1.1 数据链路层功能与帧
数据链路层功能:保证数据传输的有效、可靠
- 差错检测和控制
- 流量控制
- 基于速率
- 基于反馈 (常采用):接收方告诉发送方自己的处理能力水平,发送方再根据接收方的反馈发出对应的流量。
数据链路层的 PDU —— 帧
帧=帧头+载荷+帧尾帧 = 帧头+载荷+帧尾帧=帧头+载荷+帧尾
帧头:定位所需的物理地址信息。
帧尾:校验和作为帧的校验。
成帧:将物理层的位流分散到离散的帧中。
- 四个成帧方法 —— 字符计数法、字节填充的标志字节法、比特填充的标志比特法、物理层编码违例法
3.1.2 字符计数法 (不用)
- 发送方:在每个帧头部的第一个字段,标识该帧的长度,即一共有多少字符数。
- 接收方:根据帧头部第一个字段,得知该帧在何时结束。
- 优点
- 简单,易实现。
- 缺点
- 一旦出错,无法恢复,因此极少使用。
3.1.3 字节填充的标志字节法 (常用)
考虑了重新同步问题,每一帧采用一个特殊的字节作帧界,即帧的开始和结束。
特殊字节即为标记字节 (Flag Byte),常用于 PPP (点对点) 协议中。
问题 1:传输的数据中有标记字节。
解决 1:转义符,在特殊数据前加转义符。(扫描到转义符时,会删除转义符并取后一个字符)
问题 2:任意比特数的帧不适用,必须是 8 位整数倍。
解决 2:比特标记法。(比特填充的标志比特法)
3.1.4 比特填充的标志比特法 (常用)
方法
- 帧标记
- 将所有需要传输的数据以比特位一字排开,并以特殊的位模式 01111110 作为帧标志,即一个帧的开始 (同时标志前一个帧的结束)
- 数据中出现帧标记
- 当帧内容中出现一个与帧标志相同的位串 01111110 时,则在 5 个 1 后插入一个 0,即变成 01111101,接收方将自动删除第 5 个 1 后的 0。这种方法为位填充法 (零比特填充法),也称为透明传输。
- 数据恢复
- 如果由于干扰,一个帧没有正确接收,则可扫描接收串,一旦扫描到 01111110,即新的一帧从此开始,可以重新进行同步。
- 帧标记
例子
优点
传输任意比特数的帧
传输效率更高
3.1.5 物理层编码违例法
- 特点:将冗余信号作为帧界。
- 例子
- 在4B/5B编码中,4B被映射为5B传输,32个模式中,只用到16个,剩下的可以用帧界。
- 在曼彻斯特编码中,编码过程只用到了高电平到低电平的跳变,以及低电平到高电平的跳变。而低到低与高到高并没有使用,因此我们可以将这两种跳变作为帧界。
- 优点:用冗余信号作为帧界,避免混淆,也不需要填充,传输效率高。
3.1.6 课程总结
- 数据链路层在哪里?(物理层之上,网络层之下)
- 数据链路层的主要功能是什么?(差错检测和控制、流量控制)
- 字符计数法成帧的主要缺点是什么?(一旦出错,无法恢复)
- 字节填充的标记字节法的基本原理是什么?
- 比特填充的标记比特法的基本原理是什么?
3.2 差错处理概述
3.2.1 差错处理概述
- 差错类型
- 单个错误:分散在各块数据中
- 突发错误:集中于一个数据块,整个块都是错误
- 差错处理
- 纠错
- 纠错码 (前向纠错技术):发现错误,从错误中恢复出正确的来。有线网络中极少使用,主要用于无线网络中。
- 检错
- 检错码:只能发现错误,不能从错误中恢复,但可采用重传恢复。局域网中主要采用检错码。
- 纠错
- 奇偶校验
- 核心思想:在数据位之后加一位校验位
- 奇校验:校验位的添加,确保 数据位+校验位 一共有奇数个"1"。
- 偶校验:校验位的添加,确保 数据位+校验位 一共有偶数个"1"。
3.2.2 海明距离
码字:包含数据位和校验位的 n 位单元 (模式)
定义
- 两个码字的海明距离:两个码字之间不同位的数目。
- 全部码字的海明距离:全部码字中任意两个码字之间海明距离的最小值。
海明距离意义:如果海明距离为d,则一个码字需要发生d个1位错误才能变成另外一个码字。
海明距离与检错的关系
- 海明距离为d+1的编码能检测出d位差错
- 例如
海明距离与纠错的关系
- 海明距离为 2d+1 的编码,能纠正 d 位差错。因为此时任何一个码字有d位发生差错,它仍然距离原来的码字距离最近,可以直接恢复为该码。
海明距离越大,纠错能力越强,检错能力也越强。但是一个系统中海明距离增加,合法码字就减少,传输效率降低。
3.2.3 课程总结
- 什么是码字?
- 什么是两个码字的海明距离?什么是全部码字的海明距离?
- 差错的类型有哪两种?
- 海明距离跟检错有什么关系?
- 海明距离跟纠错有什么关系?
3.3 纠 1 位错的海明码
3.3.1 数据位与冗余位
码字长度 = n,数据位 = m,冗余位 = r,要实现纠正 1 位错,即海明距离为 3,则有下述公式。
(n+1)2m≤2n,(m+r+1)≤2r(n+1)2^m \leq 2^n,(m+r+1)\leq 2^r(n+1)2m≤2n,(m+r+1)≤2r
公式推导
- n=m+rn = m+rn=m+r ,合法码字个数为 2m2^m2m ,全部码字个数为 2n2^n2n。
- 要实现每个合法码字发生一位错误之后都是一个新的码字,则 (n+1)2m≤2n(n+1)2^m \leq 2^n(n+1)2m≤2n。
3.3.2 海明纠错码
海明纠错码特点
- 每一个码字,从左到右编号,1~n。
- 校验位:编号为 2 的幂的位,如1、2、4、8、16等。
- 校验位可以自己设置。依据为包括自身在内的一些位的集合的奇偶值。
- 数据位:3、5、7、9、10、11等,数据位直接填入我们要传输的数据。
发送方发送海明纠错码
- 校验位的值为该校验位对应数据集合的偶校验的值,对应数据集合为所有二进制拆分下包含该数字的数据位。
例如,m = 7,r = 4。
- 校验位的值为该校验位对应数据集合的偶校验的值,对应数据集合为所有二进制拆分下包含该数字的数据位。
接收方纠错
- 令差错计数器 counter=0counter=0counter=0 。依次检查每一位校验位,如果某一位校验位的值出错,则 counter=counter+该校验位的编号counter = counter+该校验位的编号counter=counter+该校验位的编号。
- 最后,如果 counter=0counter=0counter=0,则无差错。若 counter≠0counter \not= 0counter=0,则出错,出错位为 countercountercounter 值所对应的位,因为某一位发生错误会影响到该位拆成二进制形式下的每一个 “1” 的位置。
3.3.3 课程总结
- 16 位数据位,需要纠 1 位错,冗余位应该为多少?
- 纠 1 位错的海明码,发送方怎样确定校验位?
- 纠 1 位错的海明码,接收方怎样判定收到的码字是否正确?如果出错了,怎么纠正成正确的码字?
3.4 检错码
3.4.1 奇偶校验码
- 偶校验,保证码字中 “1” 的个数为偶数。
- 奇校验,保证码字中 “1” 的个数为奇数。
- 如果偶数个位同时发生错误,则奇偶校验会失效,因此奇偶校验正确判断的概率为 50%。
3.4.2 互联网校验和
- 按照 N 位码字,进行模 2 加运算。
- 发送方将运算结果追加到报文的尾部。
- 例如,互联网 16 位补码校验和。
- 发送方:将待校验的相邻字节成对组成16比特的整数一行,按行从低位开始计算其模 2 和;并将结果按位取反码,作为校验和取值。
- 接收方:检查校验和时,将所有字节,包括校验和,进行相加并求二进制反码。若结果为全 1,则无误,否则传输错误。
- 注意:若某列的模 2 和有溢出,则向高位进位,如果高位产生进位,循环向低位进位。
3.4.3 循环冗余校验码 (CRC)
工作原理
- k位的帧=k−1次的多项式k\ 位的帧 = k-1\ 次的多项式k 位的帧=k−1 次的多项式
- 例如,101100110110011011001,可以看成是 x6+x4+x3+x0x^6+x^4+x^3+x^0x6+x4+x3+x0 。
- 双方约定一个生成多项式 G(x)G(x)G(x),G(x)G(x)G(x) 为 rrr 阶,rrr 就是冗余位。
- m 位帧的多项式,m > r,M(x) > G(x)。
- xrM(x)G(x)=Q(x)+R(x)\frac{x^rM(x)}{G(x)}=Q(x)+R(x)G(x)xrM(x)=Q(x)+R(x),R(x)R(x)R(x) 为余数,Q(x)Q(x)Q(x) 为商。
- xrM(x)−R(x)G(x)=Q(x)\frac{x^rM(x)-R(x)}{G(x)}=Q(x)G(x)xrM(x)−R(x)=Q(x),消除余数。
- xrM(x)−R(x)x^rM(x)-R(x)xrM(x)−R(x) 即为 CRC 校验码。
- 注意:此处的除法以及加减法过程均为异或运算,与实际中的运算不同。
- 接收方检验
- CRC校验码G(x)\frac{CRC校验码}{G(x)}G(x)CRC校验码 的余数为0,则传输无误,否则传输错误。
- k位的帧=k−1次的多项式k\ 位的帧 = k-1\ 次的多项式k 位的帧=k−1 次的多项式
例如
帧:1101011011(m=10)1101011011\ (m=10)1101011011 (m=10)
M(x)=x9+x8+x6+x4+x3+x+1M(x)=x^9+x^8+x^6+x^4+x^3+x+1M(x)=x9+x8+x6+x4+x3+x+1
令 G(x)=x4+x+1G(x)=x^4+x+1G(x)=x4+x+1 (r=4(r=4(r=4阶))),即 100111001110011。
T(x)=x4M(x)=x13+x12+x10+x8+x7+x5+x4T(x)=x^4M(x) = x^{13}+x^{12}+x^{10}+x^8+x^7+x^5+x^4T(x)=x4M(x)=x13+x12+x10+x8+x7+x5+x4 (相当于在原码字后加 rrr 个 000 )
计算 1101011011000010011\frac{11010110110000}{10011}1001111010110110000 得到余数 111011101110,11010110110000−1110=1101011011111011010110110000-1110=1101011011111011010110110000−1110=11010110111110,因此编码后 CRC\text{CRC}CRC 码 =11010110111110=11010110111110=11010110111110 。
- 当码字到达接收方时。如果CRC码在接收端能被 100111001110011 整除则说明接受正确,否则即可检测到出错。
生成多项式 G(x)G(x)G(x) 国际标准
- CRC-121212:x12+x11+x3+x2+x1+1x^{12}+x^{11}+x^3+x^2+x^1+1x12+x11+x3+x2+x1+1
- CRC-161616:x16+x15+x2+1x^{16}+x^15+x^2+1x16+x15+x2+1
- CRC-CCITT:x16+x12+x5+1x^16+x^12+x^5+1x16+x12+x5+1,用于长度字符为 8 位。
- CRC-32,用于以太网计算循环冗余校验。
- G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x3+x+1G(x)=x^{32}+x^{26}+x^{23}+x^{22}+x^{16}+x^{12}+x^{11}+x^{10}+x^8+x^7+x^5+x^4+x^3+x+1G(x)=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x3+x+1
练习
- G(x)=x3+x2+1G(x)=x^3+x^2+1G(x)=x3+x2+1,待传送的原始码字分别为 111111111111 和 110011001100,求 CRC 编码之后的码字分别是什么?
G(x)G(x)G(x) 对应 110111011101,1111左移3位=11110001101=1011+111(余)\frac{1111左移3位=1111000}{1101}=1011+111(余)11011111左移3位=1111000=1011+111(余) ,CRC =1111000−111=1111111=1111000-111=1111111=1111000−111=1111111
G(x)G(x)G(x) 对应 110111011101,1100左移3位=11000001101=1001+101(余)\frac{1100左移3位=1100000}{1101}=1001+101(余)11011100左移3位=1100000=1001+101(余),CRC =1100000−101=1100101= 1100000-101=1100101=1100000−101=1100101
- G(x)=x3+x2+1G(x)=x^3+x^2+1G(x)=x3+x2+1,待传送的原始码字分别为 111111111111 和 110011001100,求 CRC 编码之后的码字分别是什么?
3.4.4 课程总结
- 什么是检错码?
- 采用循环冗余校验码,发送方怎么做?
- 采用循环冗余检验码,接收方怎么做?
- 循环冗余校验码,能够检查出多少位错误?
3.5 基本数据链路协议 (1-3)
3.5.1 前提假设
三个协议都是单工协议,即在某一时刻信道是单向的。
前提假设
- 物理层、数据链路层和网络层各自是独立的处理进程。
- 机器 A 希望向 B 发送的是一个可靠的、面向连接的长数据流。
- 假设机器不会崩溃,即使崩溃我们也不会处理因崩溃而产生的错误。
- 从网络层拿到的数据是纯的数据,即这个数据是作为纯数据装到帧的载荷之中。
三个协议的共同头文件
#define MAX_PKT 1024 /* 定义了包的字节大小 */ #define inc(k) if(k < MAX_SEQ) k = k + 1; else k = 0;typedef enum {false, true} boolean; /* boolean类型 */ typedef enum {frmae_arrival, cksum_err, timeout} event_type; /* 事件类型(帧到达、校验和错误、定时器超时) */ typedef unsigned int seq_nr; /* sequence or ack numbers */ typedef struct {unsigned char data[MAX_PKT]; } packet; /* packet的定义 */ typedef enum {data, ack, nak} frame_kind; /* frame_kind的定义 */typedef struct {frame_kind kind; /* 帧的类型 */seq_nr seq; /* sequence number (帧的序列号) */seq_nr ack; /* acknowledgement number (帧的确认号) */packet info; /* the network layer packet (帧的载荷) */ } frame;void from_network_layer(packet *p); /* 从网络层拿包 */ void to_physical_layer(frame *r); /* 将帧传到物理层 */void from_physical_layer(frame *r); /* 从物理层拿帧 */ void to_network_layer(packet *p); /* 将包传到网络层 */void wait_for_event(event_type *event); /* 等待某个事件发生 */void start_timer(seq_nr k); /* 重传定时器开始 */ void stop_timer(seq_nr k); /* 重传定时器停止 */void start_ack_timer(void); /* 稍带确认定时器开始 */ void stop_ack_timer(void); /* 捎带确认定时器停止 */
3.5.2 无限制的单工协议 (协议 1 )
前提假设 (乌托邦环境)
- 数据单向传送
- 收发双方的网络层都处于就绪状态 (随时待命)
- 对帧的处理时间忽略不计 (瞬间完成)
- 可用的缓存空间无穷大 (无限空间)
- 数据链路层之间的信道不会损坏并且不丢帧 (完美通道)
发送方
void sender1(void){frame s;packet buffer;while(true){from_network_layer(&buffer); /* 从网络层拿包,拿到之后直接放入buffer中 */s.info = buffer; /* 组成了一个帧 */to_physical_layer(&s); /* 把帧传给物理层 */} }
接收方
void receiver1(void){ /* 只要帧到达,就开始收帧(解封装) */frame r;event_type event;while(true){wait_for_event(&event); /* 等待一个事件的到来(帧到达) */from_physical_layer(&r); /* 从物理层拿比特流 */to_network_layer(&r.info); /* 将帧中的包传给网络层 */} }
3.5.3 单工停-等协议 (协议 2 )
改进
- 取消了协议 1 中接收方允许无限量接受的假设。因此接收方有可能被大量涌入的数据所淹没。
解决方案
- 接收方收到一个数据,如果它有处理能力的话,它会回发一个哑帧给对方。
- 只要发送方收到了哑帧,它就知道接收方已经做好了接收数据的准备,因此可以继续发下一帧的数据。
半双工协议
- 此时数据传输已经是双向了,严格的说这应该是一个半双工协议。
发送方
void sender2(void){frame s;packet buffer;event_type event; /* 变量取值为帧到达 */while(true){from_network_layer(&buffer); /* 从网络层拿包,拿到之后直接放入buffer中 */s.info = buffer; /* 组成了一个帧 */to_physical_layer(&s); /* 把帧传给物理层 */wait_for_event(&event); /* 等待哑帧 */} }
接收方
void receiver2(void){ /* 只要帧到达,就开始收帧(解封装) */frame r;event_type event;while(true){wait_for_event(&event); /* 等待一个事件的到来(帧到达) */from_physical_layer(&r); /* 从物理层拿比特流 */to_network_layer(&r.info); /* 将帧中的包传给网络层 */to_physical_layer(&s); /* 向发送方发送一个哑帧 */} }
3.5.4 有噪声信道的单工协议 (协议 3 )
改进
- 在协议 2 基础上取消了帧传输不会发生错误的假设,即允许信道中存在噪声。
- 因此会出现如下问题:
- 接收方收到帧之后,发现该帧无法通过校验,即发生了错误。
解决方
增加了接收方对正确帧的确认。
- 任何时候接收方收到的帧通过了校验,接收方才会向发送方发一个确认帧。
- 发送方只有当收到了确认之后,才会去发下一帧。
发送方增加计时器。
- 目的:避免数据帧或确认帧丢失后,发送方持续等待的情况。
- 发送方发出数据帧的同时启动定时器,如果定时器超时了仍未收到确认帧,发送方会重新发送数据帧,直到接收方回复确认帧。
给每一个帧一个独一无二的序号。
- 目的:数据帧未到但定时器超时,接收方同时收到了数据帧以及重传帧,帧序号用于区别重传帧。
- 帧序号还能用于对帧的重排与重组。
肯定确认重传机制 (PAR)
名称
- 肯定确认重传机制-PAR (Positive Acknowledgement with Retransmission)
- 也称自动重传请求 - ARQ (Automatic Repeat ReQuest)
具体过程
- 发送方每发出一个帧,它都启动一个重传定时器,期望在超时之前收到对方的确认。如果超时之前收到了就拆除定时器,否则发方重传数据帧并重新设置定时器。
发送方
void sender3(void){seq_nr next_frame_to_send;frame s;packet buffer;event_type event; next_frame_to_send = 0;from_network_layer(&buffer);while(true){s.info = buffer;s.seq = next_frame_to_send;to_physical_layer(&s);start_timer(s.seq); /* 发出帧之后,启动定时器 */wait_for_event(&event);if(event == frame_arrival){from_physical_layer(&s);if(s.ack == next_frame_to_send){stop_timer(s.ack); /* 收到确认后,拆除定时器 */from_network_layer(&buffer);inc(next_frame_to_send); /* 模2计数 */}}} }
接收方
void receiver3(void){seq_nr frame_expected;frame r,s;event_type event;frame_expected = 0;while(true){wait_for_event(&event); /* 等待一个事件的到来(帧到达) */if(event == frame_arrival){from_physical_layer(&r);if(r.seq == frame_expected){to_network_layer(&r.info);inc(frame_expected); /* 模2计数 */}s.ack = 1 - frame_expected; /* 对收到的帧做一个确认 */to_physical_layer(&s); /* 将确认帧发送给对方 */}} }
提高传输效率
- 全双工:每个用户既是发方又是收方,两方可以互相来发数据。
- 捎带确认:接收方将确认帧放到一个将要外发的数据帧中,搭便车。
- 捎带确认要启动一个捎带确认的定时器,避免等待时间过长,发送方重传。
- 批发数据 (管道化的技术)
- 等待第一个确认帧的时候继续发后续的数据帧。等后续数据帧发出去之后,第一个确认帧就到达了。
3.5.5 课程总结
- 协议 1 :乌托邦的单工协议
- 协议 2 :做了简单的流量控制,防止接收方被数据所淹没
- 协议 3 :解决噪声信道带来的错误,引出肯定确认技术。
- 问题
- 如何解决接收方被大量数据所淹没?(哑帧)
- 肯定确认重传技术是怎样工作的?
- 重传定时器什么时候启动,什么时候拆除?
- 接收方为什么会收到重复帧?
- 如果发送的帧丢失了,意味着发方永远收不到这帧的确认,发方会死等确认帧 (永远不可能到来) 的到来吗?
- 什么是捎带确认?
3.6 滑动窗口协议 (协议4)
3.6.1 滑动窗口基本概念
每个待发送帧被赋予一个序列号seq
- seq的取值范围是 000~2n2^n2n-111 (nnn 位字段)
建立缓冲区
- 发送窗口:缓存已发送、待确认的帧
- 顺序接收来自网络层的分组,成帧,赋予序列号
- 最多保存 W 个已经发送、等待确认的帧
- 窗口达到最大值 W 时强制关闭网络层
- 接收窗口:缓存期待接收的帧 (序号)
- 对进入窗口的帧顺序提交网络层,产生确认
- 落在窗口外的帧被丢弃
- 发送窗口:缓存已发送、待确认的帧
3.6.2 窗口大小为1的滑动窗口协议
接收窗口滑动的条件
- 接收方收到帧之后,核对收到的帧的序列号是否是 frame_expected\text{frame\_expected}frame_expected。如果是就接受这一帧。接受之后就向下滑动窗口,即 frame_expected=frame_expected+1\text{frame\_expected} = \text{frame\_expected}+1frame_expected=frame_expected+1。
发送窗口滑动的条件
- 发送方收到接收方的捎带确认之后,核对这个确认帧号是否是 next_frame_to_send\text{next\_frame\_to\_send}next_frame_to_send。如果是,则发送方移动窗口,即 next_frame_to_send=next_frame_to_send+1\text{next\_frame\_to\_send}=\text{next\_frame\_to\_send}+1next_frame_to_send=next_frame_to_send+1。
全双工代码实现
void protocol4(void){seq_nr next_frame_to_send; /* 即将或已经发送但还未被确认的帧序号 */seq_nr frame_expected; /* 期望收到的帧序号 */frame r, s;packet buffer;event_type event;next_frame_to_send = 0; /* 从0号帧开始发送 */frame_expected = 0; /* 接收方开始期待的是对方发来的0号帧 */from_network_layer(&buffer);s.info = buffer;s.seq = next_frame_to_send; /* 初始为0,发送0号帧 */s.ack = 1 - frame_expected; /* 初始为1,表示收到了1号帧 */to_physical_layer(&s);start_timer(s.seq); /* 启动计时器 */while(true){wait_for_event(&event);if(event == frame_arrival){from_physical_layer(&r);if(r.seq == frame_expected){ /* 接收方收到了期待帧 */to_network_layer(&r.info);inc(frame_expected); /* 移动接收窗口 */}if(r.ack == next_frame_to_send){ /* 发送方收到了接收方的捎带确认 */stop_timer(r.ack); /* 停止计时器 */from_network_layer(&buffer);inc(next_frame_to_send); /* 移动发送窗口 */}}s.info = buffer;s.seq = next_frame_to_send; /* 发送下一帧 */s.ack = 1 - frame_expected; /* ack表示收到的帧 */to_physical_layer(&s);start_timer(s.seq); /* 重新开始计时 */} }
窗口大小为 1 的滑动窗口协议的基本工作原理
特点
- 序列号 seq 和确认值 ack “0”、"1"交替。
- 滑动窗口长度 W=1W=1W=1,收到确认才移动窗口。
- 接收方保证按顺序将接收到的正确帧一次性地提交到网络层。
正常工作情况
异常情况一:对重复帧的差错控制
- 即使不断发生超时重传,协议仍能正常工作,不过信道利用率会大幅下降。
异常情况二:同步开始发送过程的差错控制
- A、B同时开始发送帧,也会导致大量重复帧的出现,但协议仍能正常工作,不过大量重复帧浪费带宽。
3.6.3 协议 4 的信道利用率
- 假设:忽略接收方处理到达帧的时间
- 事实上,在低速信道上,来回时间 (RTT-the round-trip time)可能非常大,发送方在这段时间处于阻塞状态。
- 举例:卫星信道
- 信道传输速率 b=50kbpsb = 50\ kbpsb=50 kbps,传输延迟 (来回时间) R=500msR=500\ msR=500 ms,每帧的大小 k=1000bitk=1000\ bitk=1000 bit
- 计算方式 (一)
- 在源端发送数据帧所需时间 Tf=k/b=20msT_f=k/b=20\ msTf=k/b=20 ms。
- 从发送完毕到确认帧返回所需时间 (双程延迟) R=500msR=500\ msR=500 ms。
- 从开始发送到确认返回一共所需时间 (Tf+R)=20+500=520ms(T_f+R)=20+500=520\ ms(Tf+R)=20+500=520 ms。
- 线路利用率 TfTf+R=20520=3.85%\frac{T_f}{T_f+R}=\frac{20}{520}=3.85\%Tf+RTf=52020=3.85% 。
- 计算方式 (二)
- 线路利用率 kk+bR=3.85%\frac{k}{k+bR}=3.85\%k+bRk=3.85%
- 提高信道利用率 (窗口大小为 W)
- 信道利用率=W∗TfTf+R=W∗kk+bR=100%信道利用率=\frac{W*T_f}{T_f+R}=\frac{W*k}{k+bR}=100\%信道利用率=Tf+RW∗Tf=k+bRW∗k=100%
- 在上述卫星信道例子中,W=26W=26W=26 时利用率能够达到 100%100\%100%。即在发送第一个帧出去,等待确认帧的过程中,继续发送26个帧。刚好发完26个帧后,第一个确认帧到达。
- 如何找到一个合适的 WWW 值?
- 信道容量:一帧从发出到目的期间,信道上能够容纳的帧数量。
- 延迟:从帧出发到它到达目的所需时间。
- 带宽-延迟积:即 带宽延迟积=带宽∗延迟=B∗D带宽延迟积=带宽*延迟=B*D带宽延迟积=带宽∗延迟=B∗D,W=2∗BDk+1W=\frac{2*BD}{k}+1W=k2∗BD+1。通常难以达到 100%100\%100%,因此W≤2∗BDk+1W\leq \frac{2*BD}{k}+1W≤k2∗BD+1。
- 例题
3.6.4 课程总结
- 为什么提出滑窗技术?
- 什么是发送窗口?
- 发送窗口什么时候滑动?
- 什么是接收窗口?
- 接收窗口什么时候滑动?
- 什么是带宽延迟积?
- 窗口值怎么确定?跟哪些因素有关?
3.7 回退n帧与选择性重传(协议5、6)
3.7.1 批量发送面临的问题
- 出错情况
- 连续发送W个数据帧,其中有一帧出错,但其后续帧被成功发送,此时应该如何处理?
- 接收方接收策略选择
- 丢弃错帧及后续帧,其后续帧因不是期望接受帧也被丢弃
- 丢弃错帧,缓存后续正确接收帧
- 对应发送方的重传策略选择
- 缓存在发送窗口中的出错帧以及其后续帧全部重发 —— 协议5:回退n帧
- 只重发出错帧 —— 协议6:选择性重传
3.7.2 回退n帧 (协议5)
接收方与发送方策略
- 接收方 —— 丢弃错帧及后续帧,其后续帧因不是期望接受帧也被丢弃
- 接受窗口 W=1W=1W=1
- 发送方 —— 缓存在发送窗口的出错帧以及其后续帧全部重发
- 接收方 —— 丢弃错帧及后续帧,其后续帧因不是期望接受帧也被丢弃
回退n帧协议的基本概念
- 定义序列号 seq 的取值范围和滑动窗口 W
- 发送方连续发送至发送窗口满
- 接受窗口为 1,对出错帧不确认 (引发超时)
- 发送方超时重传,从未被确认帧开始
回退n帧工作原理
累计确认
- 回退n帧采用了累计确认,发送方会开辟一个较大的空间保存着所有未被确认的帧。
- n号帧的确认到达时,暗含:n-1、n-2…等 n 号帧之前的帧也被确认。
- 采用累计确认之后,收到了 n 帧的确认,n帧之前的帧都可从缓存中删掉。
滑动窗口大小 W 的选择
- 发送窗口:W≤MAXSEQW\leq \text{MAXSEQ}W≤MAXSEQ
- 比如,序列号由 3 位表示,3位表示的最大数为7,则窗口最大为7。
- 如果 W=8W=8W=8,则会出错。
- 第一次发送 0-7 帧,接收方回复 ack=7 表示都收到了。
- 第二次继续发送0-7帧,但这次帧在传输过程中出错,接收方仍回复 ack=7,由此导致错误。
总结
- 回退n帧,需要发送方付出更多的缓存代价。
- 适合出错率较少的高速信道。
- 回退n帧的窗口数
- 发送窗口:W≤MAXSEQW\leq \text{MAXSEQ}W≤MAXSEQ
- 接受窗口:W=1W=1W=1
- 回退n帧,需要发送方付出更多的缓存代价。
3.7.3 选择性重传 (协议6)
接收方与发送方策略
- 接收方 —— 丢弃错帧,缓存后续正确接收帧
- 发送方 —— 只重发出错帧
工作原理
- 发送方
- 正常发送:对帧编号,待确认帧缓存
- 收到确认:释放确认帧所占缓冲区,滑动发送窗口
- 重传的差错帧超时:重传缓存的最后被确认帧以后的那一帧
- 接收方
- 正常接收:上交网络层、回送确认,滑动接收窗口
- 收到非期望的正确帧:缓存,回送对接收的最后正确帧的确认
- 收到重传帧:将缓存帧排序上交,回送确认,滑动接收窗口
- 三大关键步骤
- 接收方收到非期望的正确帧 —— 缓存
- 发送方选择帧seq2重传
- 接收方收到重传帧seq2 —— 与之前的帧排序上交网络层
- 发送方
否定确认 NAK
- 当我们收到第二号出错帧时,之前是直接丢弃等发送方超时重传。
- 现在可以使用NAK,收到第二号出错帧之后,向发送方发送 NAK=2,明确告诉发送方第二号帧出错。
- 加快重传节奏。
协议5与协议6的比较
- 回退n帧
- 发送方需要较大的缓冲区,以便重传
- 重传帧数多,适用于信道出错率较小的情况
- 选择重传
- 接收方需要较大的缓冲区,以便按正确顺序将分组提交网络层
- 重传帧数少,适于信道质量不好的情况
- 回退n帧
滑动窗口 W 大小的选择
- 接收窗口:W=MAXSEQ+12W=\frac{\text{MAXSEQ}+1}{2}W=2MAXSEQ+1,保证接收方新老窗口不相交。发送窗口通常小于接收窗口。
- 比如,序列号为3位,则 MAXSEQ=7\text{MAXSEQ} = 7MAXSEQ=7,W=4W = 4W=4。
- 例如W=7,即会出错。
- 一开始接收窗口为 01234560\ 1\ 2\ 3\ 4\ 5\ 60 1 2 3 4 5 6,发送方发送 0-6,接收方收到之后,接收窗口变为 70123457\ 0\ 1\ 2\ 3\ 4\ 57 0 1 2 3 4 5,并向发送方发送 0-6 号帧的确认帧。
- 但是0-6号帧的确认帧在传输过程中全部丢失,发送方的0号帧超时重发。
- 接收方收到0号帧后,发现接收窗口中有0号帧,误以为是新帧便将其缓存。但该0号帧只是一个重传帧,由此导致了协议错误。
- 因此使得协议不发生错误,只能保证接收方新老窗口不相交,即 W=MAXSEQ+12W=\frac{\text{MAXSEQ}+1}{2}W=2MAXSEQ+1。
例题
3.7.4 三个滑动窗口协议窗口大小
协议4:滑动窗口 协议5:回退 n 帧 协议6:选择性重传 发送窗口 (SWnd) 0<SWnd≤10<\text{SWnd}\leq 10<SWnd≤1 0<SWnd≤MAXSEQ0<\text{SWnd}\leq \text{MAXSEQ}0<SWnd≤MAXSEQ 0≤SWnd≤RWnd0\leq \text{SWnd}\leq \text{RWnd}0≤SWnd≤RWnd 接收窗口 (RWnd) RWnd=1\text{RWnd}=1RWnd=1 RWnd=1\text{RWnd}=1RWnd=1 RWnd=MAXSEQ+12\text{RWnd}=\frac{\text{MAXSEQ}+1}{2}RWnd=2MAXSEQ+1
3.7.5 课程总结
- 回退 n 帧的工作原理是怎样的?
- 什么是累计确认?
- 如何确定回退 n 帧协议的窗口数?
- 什么是否定确认重传?有什么作用?
- 选择性重传的工作原理是怎样的?
- 如何确定选择性重传协议的窗口数?
计算机网络超详细笔记(三):数据链路层相关推荐
- 学习javascript这一篇就够了超详细笔记(建议收藏)上
学习javascript这一篇就够了超详细笔记(建议收藏)上 1.初识 计算机基础导读 编程语言 计算机基础 初识js 浏览器执行 js组成 js初体验-三种书写位置 js注释 js输入输出语句 2. ...
- Java并发编程(中下篇)从入门到深入 超详细笔记
接上一篇博客笔记:Java并发编程(中上篇)从入门到深入 超详细笔记_未来很长,别只看眼前的博客-CSDN博客https://blog.csdn.net/weixin_53142722/article ...
- (超详细笔记整理)动力节点_老杜 | JavaSE零基础 :P329(方法) - P479
JAVA基础学习 第二篇文章的连接: (超详细笔记整理)动力节点_老杜 | JavaSE进阶 [P486之后]. 文章目录 JAVA基础学习 方法 Java的主要内存空间 栈数据结构 **栈数据结构: ...
- SPRING注解驱动开发-雷神课程超详细笔记
SPRING注解驱动开发-雷神课程超详细笔记 时间:2021-03-21 2022-04-06更新:最近翻起一年多前写的笔记复习,还是收获颇多,很多当时无法理解的知识现在慢慢能理解了,可能是工作一年的 ...
- 清晰易懂!关于PS入门的超详细笔记!
给大家分享一篇关于PS入门的超详细笔记!原理讲解清晰明了,虽不是新版本解析,但都是新手学习PS必掌懂的一些知识点,灰常的实用,转走收藏学习! 编辑:千锋UI设计 来源:PS学堂
- 计算机网络入门网课推荐+超详细笔记
建议看湖南科技大学的网课,讲得十分清晰明了 https://www.bilibili.com/video/BV1c4411d7jb?p=1&vd_source=ac571aae41aa0b58 ...
- Java菜鸟笔记:Java猜字母游戏完整代码 注释超详细(三次机会,计算总分,可运行)
import java.util.Scanner; import java.util.regex.Pattern; /*** 猜字母游戏,程序随机生成一个五个长度不重复的字母数组,要求用户也输入五个字 ...
- 【Linux】软件包管理超详细笔记
往期内容: Linux常用指令合集 Linux文本编辑器 Linux软件包管理 Linux用户管理 Linux权限管理 文章目录 软件包管理简介 软件包分类 两种软件包的比较 源码包 RPM包 RPM ...
- Mybatis与JDBC的对比超详细笔记
1 Mybatis入门 1.1 单独使用jdbc编程问题总结 1.1.1 jdbc程序 Public static void main(String[] args) { Connec ...
- 瑞吉外卖项目 基于spring Boot+mybatis-plus开发 超详细笔记,有源码链接
本项目是基于自学b站中 黑马程序员 的瑞吉外卖项目:视频链接: 黑马程序员Java项目实战<瑞吉外卖>,轻松掌握springboot + mybatis plus开发核心技术的真java实 ...
最新文章
- C语言基础知识(自己做个笔记,云储存一下)
- NBA部署SAP HANA内存数据库
- WordPress搬家全攻略
- Redis的key和value大小限制
- 使用脚本动态操作 SVG 文档
- oracle 从pflie启动,oracle初始化参数文件管理
- oschina git服务, 如何生成并部署ssh key
- Log4j不同级别输出到不同文件的几种方式
- 【虚幻引擎UE】UE5 fbx文件导入gltf文件在线/本地导入和切换(含骨骼动画)
- 一文看尽 Stata 绘图
- Pycharm中运行yolov5-pytorch出现错误:AttributeError: ‘Hardswish‘ object has no attribute ‘inplace‘
- IDEA Git缓慢
- 题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
- linux c语言内核函数手册,Linux C函数实例速查手册
- Microsoft Office无法验证此应用程序的许可证怎么解决
- 初中计算机实践研究计划,项目式教学法在初中信息技术课堂教学中的研究与实践...
- flash引导层的应用
- mysql判断字段是否存在不存在添加字段_mysql 新增字段时判断字段是否存在
- Qt_UI_vs建工程双击ui文件没有弹出设计界面
- [转载]十六款值得关注的NoSQL与NewSQL数据库
热门文章
- Fragment中获取Activity的Context
- Exchange Server 2013部署系列之一:部署环境介绍
- (转自珊珊博客)甜甜蜜蜜走台湾 Day3
- Java中swing使用ImageIcon类添加图片
- wordpress如何隐藏后台位置?
- win10的文件夹(文件资源管理器)卡住了
- oracle数据库注册服务,oracle 共享服务联接静态注册服务
- JS 打印 data数据_用D3.js 十分钟实现字符跳动效果
- 全自动mysql数据监控平台_Prometheus+Grafana打造Mysql监控平台
- 【算法笔记】数论基础:康托展开(全排列和序号之间的映射)