前言

如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。

文章目录

  • 前言
    • 第三章 数据链路层
      • 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,则传输无误,否则传输错误。
  • 例如

    • 帧: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

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
3.7.3 选择性重传 (协议6)
  • 接收方与发送方策略

    • 接收方 —— 丢弃错帧,缓存后续正确接收帧
    • 发送方 —— 只重发出错帧
  • 工作原理

    • 发送方

      • 正常发送:对帧编号,待确认帧缓存
      • 收到确认:释放确认帧所占缓冲区,滑动发送窗口
      • 重传的差错帧超时:重传缓存的最后被确认帧以后的那一帧
    • 接收方
      • 正常接收:上交网络层、回送确认,滑动接收窗口
      • 收到非期望的正确帧:缓存,回送对接收的最后正确帧的确认
      • 收到重传帧:将缓存帧排序上交,回送确认,滑动接收窗口
    • 三大关键步骤
      • 接收方收到非期望的正确帧 —— 缓存
      • 发送方选择帧seq2重传
      • 接收方收到重传帧seq2 —— 与之前的帧排序上交网络层
  • 否定确认 NAK

    • 当我们收到第二号出错帧时,之前是直接丢弃等发送方超时重传。
    • 现在可以使用NAK,收到第二号出错帧之后,向发送方发送 NAK=2,明确告诉发送方第二号帧出错。
    • 加快重传节奏。
  • 协议5与协议6的比较

    • 回退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 帧协议的窗口数?
  • 什么是否定确认重传?有什么作用?
  • 选择性重传的工作原理是怎样的?
  • 如何确定选择性重传协议的窗口数?

计算机网络超详细笔记(三):数据链路层相关推荐

  1. 学习javascript这一篇就够了超详细笔记(建议收藏)上

    学习javascript这一篇就够了超详细笔记(建议收藏)上 1.初识 计算机基础导读 编程语言 计算机基础 初识js 浏览器执行 js组成 js初体验-三种书写位置 js注释 js输入输出语句 2. ...

  2. Java并发编程(中下篇)从入门到深入 超详细笔记

    接上一篇博客笔记:Java并发编程(中上篇)从入门到深入 超详细笔记_未来很长,别只看眼前的博客-CSDN博客https://blog.csdn.net/weixin_53142722/article ...

  3. (超详细笔记整理)动力节点_老杜 | JavaSE零基础 :P329(方法) - P479

    JAVA基础学习 第二篇文章的连接: (超详细笔记整理)动力节点_老杜 | JavaSE进阶 [P486之后]. 文章目录 JAVA基础学习 方法 Java的主要内存空间 栈数据结构 **栈数据结构: ...

  4. SPRING注解驱动开发-雷神课程超详细笔记

    SPRING注解驱动开发-雷神课程超详细笔记 时间:2021-03-21 2022-04-06更新:最近翻起一年多前写的笔记复习,还是收获颇多,很多当时无法理解的知识现在慢慢能理解了,可能是工作一年的 ...

  5. 清晰易懂!关于PS入门的超详细笔记!

    给大家分享一篇关于PS入门的超详细笔记!原理讲解清晰明了,虽不是新版本解析,但都是新手学习PS必掌懂的一些知识点,灰常的实用,转走收藏学习! 编辑:千锋UI设计 来源:PS学堂

  6. 计算机网络入门网课推荐+超详细笔记

    建议看湖南科技大学的网课,讲得十分清晰明了 https://www.bilibili.com/video/BV1c4411d7jb?p=1&vd_source=ac571aae41aa0b58 ...

  7. Java菜鸟笔记:Java猜字母游戏完整代码 注释超详细(三次机会,计算总分,可运行)

    import java.util.Scanner; import java.util.regex.Pattern; /*** 猜字母游戏,程序随机生成一个五个长度不重复的字母数组,要求用户也输入五个字 ...

  8. 【Linux】软件包管理超详细笔记

    往期内容: Linux常用指令合集 Linux文本编辑器 Linux软件包管理 Linux用户管理 Linux权限管理 文章目录 软件包管理简介 软件包分类 两种软件包的比较 源码包 RPM包 RPM ...

  9. Mybatis与JDBC的对比超详细笔记

    1      Mybatis入门 1.1    单独使用jdbc编程问题总结 1.1.1  jdbc程序 Public static void main(String[] args) { Connec ...

  10. 瑞吉外卖项目 基于spring Boot+mybatis-plus开发 超详细笔记,有源码链接

    本项目是基于自学b站中 黑马程序员 的瑞吉外卖项目:视频链接: 黑马程序员Java项目实战<瑞吉外卖>,轻松掌握springboot + mybatis plus开发核心技术的真java实 ...

最新文章

  1. C语言基础知识(自己做个笔记,云储存一下)
  2. NBA部署SAP HANA内存数据库
  3. WordPress搬家全攻略
  4. Redis的key和value大小限制
  5. 使用脚本动态操作 SVG 文档
  6. oracle 从pflie启动,oracle初始化参数文件管理
  7. oschina git服务, 如何生成并部署ssh key
  8. Log4j不同级别输出到不同文件的几种方式
  9. 【虚幻引擎UE】UE5 fbx文件导入gltf文件在线/本地导入和切换(含骨骼动画)
  10. 一文看尽 Stata 绘图
  11. Pycharm中运行yolov5-pytorch出现错误:AttributeError: ‘Hardswish‘ object has no attribute ‘inplace‘
  12. IDEA Git缓慢
  13. 题目:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。
  14. linux c语言内核函数手册,Linux C函数实例速查手册
  15. Microsoft Office无法验证此应用程序的许可证怎么解决
  16. 初中计算机实践研究计划,项目式教学法在初中信息技术课堂教学中的研究与实践...
  17. flash引导层的应用
  18. mysql判断字段是否存在不存在添加字段_mysql 新增字段时判断字段是否存在
  19. Qt_UI_vs建工程双击ui文件没有弹出设计界面
  20. [转载]十六款值得关注的NoSQL与NewSQL数据库

热门文章

  1. Fragment中获取Activity的Context
  2. Exchange Server 2013部署系列之一:部署环境介绍
  3. (转自珊珊博客)甜甜蜜蜜走台湾 Day3
  4. Java中swing使用ImageIcon类添加图片
  5. wordpress如何隐藏后台位置?
  6. win10的文件夹(文件资源管理器)卡住了
  7. oracle数据库注册服务,oracle 共享服务联接静态注册服务
  8. JS 打印 data数据_用D3.js 十分钟实现字符跳动效果
  9. 全自动mysql数据监控平台_Prometheus+Grafana打造Mysql监控平台
  10. 【算法笔记】数论基础:康托展开(全排列和序号之间的映射)