数据链路层: 可靠性传输 六个协议

可靠性传输

1. 差错控制

发送方将数据帧发送, 但是当发送方发送的是一个 1的时候此时接受方却接受的是一个 0.

(1)校验

接收方如果帧校验接受到的帧没有问题, 则对发送方发送一个肯定性的确认, 当对这个数据帧进行校验发现这个帧有问题的时候, 此时接受方一种是将这个数据帧扔掉, 另一种就是告诉发送方接收的数据帧有问题, 此时向发送方发送一个否定性确认消息.

(2)差错检测和校正

检错就是如果发现数据帧传输的有问题, 则将接受的数据帧扔掉, 校正就是如果接收方发现接收到的数据帧有问题, 就将这个数据帧进行较正最常用的校验码是CRC校验码

(2)重发

在发送方定一个定时器, 当发送端在发送数据的时候定义个时间, 当发送端发送数据后如果在定时器时间以内发视频内发送端接收到了一个确认回复, 则发送端认为接收端接受到数据, 如果发送端在定时器以内没有接收到任何接受方的确认消息, 此时发送端就认为接收端没有接受到数据.

(3)帧的编号

一个帧中包含了数据真正的数据, 帧的校验码, 帧的序号, 确认号, 校验信息, 帧头, 帧尾. 接收方在接收到帧的时候向发送方发送一个确认消息, 而这个消息可能也会在中途丢失, 此时当定时器到达时间的时候, 发送方就会再次发送一个帧, 此时为了防止帧的重复接受, 数据帧中应该包含一个编号来标示数据帧的序号. 在接受的时候, 接收方也必须发送给发送方自己接受到了那个帧, 因此数据帧中也应该包含一个确认号, 来识别接受方接受的是那个数据帧.

2. 流量控制

发送方发送数据的速度太快, 而接收方接受数据的速度太慢, 此时发送方就需要降低自己的发送速度.当发送方发送数据速度非常快, 而接受方接收数据的速度又特别的满, 此时在接收方设置一个缓冲区, 当缓冲区满达到一定限度的时候, 此时的接受方就给发送方发送一个信息, 告诉发送方让其暂停发送等候通知.

基本数据链路协议

wait_for_evet(&event)
其中参数 event 就是需要等待的事件
每一层都是一个对应的进程, 它们都是处于一个等待的状态, 对于发送方来说, 网络层有数据要交给数据链路层, 数据链路层对应的进程就要等待网络层将准备好的数据交给自己, 然后数据链路层将数据进行封装交给物理层, 物理层将数据发送出去, 对于接收方, 数据链路层时刻准备着物理层将数据交给自己, 然后数据链路层将数据进行解包再将数据交给网络层.

1. 无限制的单工协议

(1)简化一

A 和 B 之间的信道传输不会出错, 因此在传输的过程中就不需要进行差错检验

(2)简化二

A 和 B 之间在传输的过程中不会接受端可以无限的进行数据的接收
因此有了上面两个简化的话, 那么对于数据链路层来说, 它只管进行数据的封装以及上下层之间的交互即可, 其他的任务都不用管. 发送方只管将物理层的数据发送出去即可. 数据链路层每次去问网络层看有没有数据需要自己去传送, 如果没有就继续dengdai,如果有数据需要自己传送, 那么就从 wait_for_event 这个函数中跳出

//发送方
void sender1(vod)
{frame s;packet buffer;while(ture){from_network_layer(&buffer);s.info - buffer;//数据链路层将网络层传下来的数据作为自己的数据部分放到 info 中, 帧的封装to_physicl_layer(&s);//数据链路层将自己的帧作为参数传给物理层}
}

对于接受方而言, 接收方只需要一直等待, 只要有物理层给自己发送数据, 接受方就将数据直接接受, 然后将数据解包送给上面的网络层

//接收方
void receiver1(void)
{frame r;event_type event;while(ture){wait_for_evnet(&event);//等待物理层给自己发送数据from_physical_layer(&r);//将物理层给出的数据进行解包to_network_layer(&r.info);//把解包的数据送给网络层}
}

2. 单工的停 - 等协议

由于接收方的接收数据的能力有限, 所以发送方不能一直发送消息, 发送方在发送完数据后就停下来, 等待接收方给自己发送一个信号, 接收方在接受到一个数据后, 将这个数据进行处理, 等到数据处理完之后接收方给发送方发送一个信号告诉发送方现在数据已经处理完毕可以进行发送了, 此时发送方接受到这个信号后才可以继续进行数据的发送.

//发送方
void sender2(vod)
{frame s;packet buffer;while(ture){from_network_layer(&buffer);s.info - buffer;//数据链路层将网络层传下来的数据作为自己的数据部分放到 info 中, 帧的封装to_physicl_layer(&s);//数据链路层将自己的帧作为参数传给物理层wait_for_event(&evet);//发送方等待接受方给自己一个信号告诉自己可以继续发送数据了}
}
//接收方
void receiver2(void)
{frame r;event_type event;while(ture){wait_for_evnet(&event);//等待物理层给自己发送数据from_physical_layer(&r);//将物理层给出的数据进行解包to_network_layer(&r.info);//把解包的数据送给网络层to_physical_layer(&s);//给发送方发送一个信号, 这个信号也是一个帧}
}

3. 有噪声的信道

在协议二的基础上加上一个定时器. 同时也有差错检验. 对于发送方必须有一个时间限制,当定时器时间已经到的时候, 接受方还没有给自己一个确认信号, 此时发送方就认为接受方没有接收到帧, 对于接受方而言, 在收到数据后将数据进行处理, 处理完数据后就需要在定时器的时间范围内给发送方一个信号, 告诉接受方自己接受到数据. 同时对于发送方而言, 为了防止帧的重复发送, 它必须有一个帧的序号, 来记录下一个发送的帧的序号, 而对于接受方为了防止接收帧的重复, 此时接受方就需要有一个帧的序号来记录下一个要接收帧的序号. 因此用一个比特位就可以记录帧的序号. 发送方发送一个 1 号帧, 接收方等待接收 1 号帧, 接受方接收到 1 号帧的时候就发送一个确认等待接受 0 号帧, 此时发送方再发送一个 0 号帧, 接收方等待接收 0 号帧, 接收方接收到 0 号帧的时候就发送一个确认信号等待接收 1 号帧. 同时协议三增加一个应答号, 应答号用来表示当前收到的是哪个帧.帧的序号是发送方发送的帧的序号, 一个比特位就好了, 应答号是接收方接收到的帧的序号, 只需一个比特位.

4. 双向传输

当接收方接收到数据后对其进行处理, 然后当它要将数据发送给上面的网络层的时候会给发送方发送一个确认信号, 而在此过程中这个信号每次都会被丢失, 此时接受方就会因为接受不到确认信号且定时器已经到达时间, 此时发送方会不断地发送重复帧, 接受方会不断地将接受到的重复帧扔掉, 此时系统会陷入死锁状态.
为了提高信道的利用率, 我们采用两条信道来解决发送方和接受方的通信. 对于发送方, 当发送方发送一个数据帧的时候, 就将它所发送的帧的类型也包括在这个帧中. 假如两个进程 A 和 B, 当 A 向 B 发送数据帧的时候, 在这个数据帧的首部加上一个帧的类型, B 接受到 A 发来的数据帧的时候就先检查数据帧的类型, 当 B 检查该数据帧的时候, 发现这是一个数据帧的时候, 此时就将这个数据帧交给上面的网络层, 再向 A 发送一个应答帧, 当 A 接收到这个帧的时候就先检查帧的类型, 当发现这是一个应答帧的时候就说明发给对方的帧对方成功接受, 此时就从网络层取下一个数据进行发送.

5. 滑动窗口

包含楼量控制, 差错处理. 每一方都有一个发送窗口, 发送窗口表示发送一次最多发送多少数据对方可以接收. 每一个接收方有一个接收窗口, 这个窗口的大小可以根据发送方的不同设定自己一次可以接收数据的接受量.

(1)滑动窗口原理(设 Wt = 5, Wr = 3)

这里写图片描述
发送方发送数据时一次发送 5 个数据帧(0 ~ 4)之后就停下来, 接受方接受数据的时候一次接受多个, 其中它接受一个数据初处理一个数据, 接受到第三个数据的时候就处理第三个数据, 当处理完第三个数据(2)的时候给发送方一个确认消息2, 此时发送方就知道接收方接受到了第三个数据了, 于是下次从 2 号数据开始发送.

(2) 一维滑动窗口协议

A 发送一个数据帧发送窗口满了, 此时就必须等待 B给 A 发送确认消息, B 接受到一个数据帧后等给 A 发送一个确认消息,A 接受到这个确认消息后知道 B 成功接受到了 自己的消息, 于是发送下一个数据帧, 到了 B 之后, B 发送一个数据给 A 时, 此时 B 的窗口已满, 于是它就停下来等待 A 的确认消息, A 接受到这个消息后就发送一个确认消息给 B, 此时 B 就知道 A 成功接受到了消息
A 发送一个帧后 B 接受到一个帧, 然后发送一个确认消息给 B, B接收到确认消息后发送

(3)后退 n 帧协议

发送方有大于 1 个的发送窗口, 接受方只有一个接受窗口. 发送端每次发送数据帧的时候一次发送一批数据帧. 当有一个帧出错, 将后面的所有的帧全部重发. 加入发送方发送 0, 1, 2, 3, 4, 5, 6 七个帧, 接受方此时接受一个 0 号帧, 处理完 1 号帧后就发送一个0 号确认消息, 此时发送方滑动窗口转过就可以发送第八个数据帧了, 接着接受方接收到了一个 1 号帧, 处理 1 号帧, 处理完之后发送一个 1 号确认消息给 发送方, 发送方就可以发送第九个数据帧了, 但是此时 2 号帧丢失了, 此时丢失的这个帧就必须等到发送方的定时器时间到的时候发送方才知道对方没有接受到 2 号帧, 于是就将2号后面所有的数据帧进行重新发送. 信道利用率较低, 适用于出错率较低的信道. 是一种实用的 PPP 可靠传输. 当数据帧的序号是 n 位的时候, 此时发送方的发送窗口是 2 ^ n - 1 个滑动窗口, 接收方的窗口数是 1

(4) 选择性重发

在后退 n 帧协议上的基础上增加的功能是对于出错的数据帧, 刚才已经发过的数据帧不用重新发送, 只对出错的数据帧进行重新发送.发送窗口大于 1, 接受窗口大于 1.

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

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

相关文章

c语言实现配置文件的读写

配置文件的格式如下&#xff1a; key1 value1 key2 value2 . . . 名值对以一个链接&#xff0c;一条记录以换行符分割 头文件&#xff1a; #include<stdio.h> #include<stdlib.h> #include <string.h> 函数原型&#xff1a; void trim(char *strIn, char *…

Educational Codeforces Round 73 (Rated for Div. 2)

A 很简单的一个模拟&#xff0c;只要前面的数字有两个以上就能合成后面的&#xff0c;我们进行一遍合成看能不能出现2048就可以了。 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include&…

数据链路层: HDLC

一. 协议机 发送方和接收方. 同时有限状态机把协议形式化为一个四元组 (S,M,I,T), 其中你S表示进程和信道可能进入的集合, M 表示数据帧的状态, I 表示进程的初始状态, T 表示两两状态之间的转化. 每个系统状态可以分为发送状态, 接受状态和信道状态. 把状态用一个点进行表示,…

Miller_Rabin算法

为了测试一个大整数是不是素数&#xff0c;我们不能够使用传统的测试是否有因子的方法&#xff0c;因为那样的时间复杂度至少也是O(n)O(n)O(n)&#xff0c;空间复杂度是O(n)O(n)O(n)&#xff08;使用线性筛数法&#xff09;&#xff0c;时间复杂度还好说&#xff0c;空间复杂度…

bob-tong 字符串函数之Strtok()函数

https://www.cnblogs.com/Bob-tong/p/6610806.html Strtok()函数详解&#xff1a; 该函数包含在"string.h"头文件中 函数原型&#xff1a; char* strtok (char* str,constchar* delimiters ); 函数功能&#xff1a;   切割字符串&#xff0c;将str切分成一个个子…

数据链路层:SLIP(串型线路IP) PPP(点对点协议)

SLIP 没有差错控制, 传输时必须知道对方IP, 传输使用于低速业务 19.2k.应用非常受限 PPP协议 1. PPP协议功能 处理错误检测 支持多协议(IP, IPX, DECnet 等) 连接时允许协商 IP 地址 允许身份验证 2. PPP 的组成 串型链路上封装数据报, 即支持异步链路也支持面向 比特…

Honeycomb——BFS

【题目描述】 传送门 【题目分析】 看起来很复杂好像还要建图什么的&#xff0c;其实直接在原图上BFS就可以了&#xff0c;设置一下方向数组&#xff0c;然后直接跑就可以了。 【AC代码】 #include<cstdio> #include<cstring> #include<algorithm> #inc…

C语言中strspn()函数和strcspn()函数的对比使用

C语言strspn()函数&#xff1a;计算字符串str中连续有几个字符都属于字符串accept 头文件&#xff1a;#include <string.h> strspn() 函数用来计算字符串 str 中连续有几个字符都属于字符串 accept&#xff0c;其原型为&#xff1a; size_t strspn(const char *str, con…

Codeforces Round #587 (Div. 3)

A 只要每两个都不一样就可以&#xff0c;一旦出现两个一样的就改一个。 #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set>using namespace std;typede…

信道分配 以太网

1.频分复用 将信道分为多个频带, 用户得到某个频带后,在通信的过程中, 自始至终都都占用这个信道.即频分复用中, 所有用户同时占用不同频带的信道 2. 时分信道 将时间划分为一段一段的等长时分复用帧, 每个用户在不同时间占用相同的数据帧 3. CSMA/CD 载波监听多点接入/碰撞…

strpbrk函数

http://blog.csdn.net/tommy_wxie/article/details/7554332 函数原型&#xff1a;extern char *strpbrk(char *str1, char *str2) 参数说明&#xff1a;str1待比较的字符串&#xff0c;str2为指定被搜索的字符串。 所在库名&#xff1a;#include <string.h> …

网络层网络层服务及其 IP 地址

ARP 协议功能 将 IP 地址通过广播(一个网段, 不能跨路由器), 目标 MAC 地址是FFFFFFFF 解析目标IP地址的 MAC 地址. IP 协议 网络层的一个协议, 是一个协议的统称, 包括 ARP(地址解析协议) 协议, ICMP(网络控制报文协议) 协议, IGMP(网际组管理协议) 协议. 其中 ICMP 和 IG…

随机生成1024个数,存入一段内存,用指针实现获取1024个数的最大数地址,最小数地址

http://blog.csdn.net/itcastcpp//details/39277193 题目&#xff1a;随机生成1024个数&#xff0c;存入一段内存&#xff0c;用指针实现获取1024个数的最大数地址&#xff0c;最小数地址&#xff0c;具体实现如下&#xff1a; [cpp] view plaincopy #include<stdlib.h> …

UVa11134

【题目分析】 觉得是一道挺考验贪心掌握程度的题目&#xff0c;我就算知道是要用贪心而且肯定和区间有关&#xff0c;肯定要进行一下排序什么的我还是没有找到合适的贪心策略。 经过大佬的博客后我才明白如何进行贪心。 如果没有任何提示看这道题&#xff0c;首先&#xff0…

传输层:IP 地址解析 路由转发

IP 地址与硬件地址 1. 地址解析 通过IP地址将其如何转换为 MAC 地址.解决同一个局域网上的主机或路由的 IP 地址和硬件地址的映射问题. 即以太网上除了主机还有路由. 即如果发出的请求所有的主机都没有做出相应, 那么该以太网上的路由会对其做出响应. (1) 以太网内部主机与…

UVa11582

一个数学问题,一旦出现循环确定循环节以后就能解决问题啦. 加上一个快速幂取模.需要注意的是数据范围是264,所以必须用unsigned long long才能解决问题. 觉得板子还是要会自己写,否则不同的题目具体有一些小的改变就会束手无策. 还有就是发现如果每次初始化数组的话就会超时,所…

输入一个单向链表,输出该链表中倒数第K个结点

http://blog.csdn.net/itcastcpp/article/details/39274891//尹成 单链表操作 #include <iostream> using namespace std; class LinkList;struct LinkNode { public:LinkNode(int value 0):m_value(value),pNext(NULL){}~LinkNode(){pNext NULL;}friend class LinkList…

网络层:构成超网(CIDR)

CIDR构成超网 CIDR消除了原来的传统的 A,B, C, D类地址, 使用了各种网络前缀来代替原来分类地址中的网络号和子网号, IP 地址由原来的三级分类又变成了两级分类. 其中网络号和子网号是一个随机的长度. 其中 CIDR 也可以使用 / 的形式来表示, 其中在 / 前面写上网络前缀的位数.…

UVa12169

我们可以暴力枚举a,然后通过x1和x3确定b的值&#xff0c;然后确定其他的数字&#xff0c;一旦出现错误就放弃这组解。 关键问题就在于如何通过a,x1,x3确定b的值 x2 ( x1 * a b) % M x3 ( x2 * a b ) % M ( ( x1 * a b ) % M * a b ) % M x3 - k * M x1 * a % M * a %…

尹成 双循环链表

今天&#xff0c;我们一起用C写一个双链表&#xff0c;具体代码如下&#xff1a; DoubleList.h具体内容如下&#xff1a; [cpp] view plaincopy #include "NodeList.h" template<typename Type> class DoublyList{ public: DoublyList() :head(ne…