计算机网络项目——最小网元设计(阶段二)
目录
- 阶段目标
- 设计描述
- 1、帧结构
- 2、帧定位
- 3、差错检测
- 4、差错控制
- 5、流量控制
- 6、长帧传输——分片
- 测试情况
- 其他想说的话
阶段目标
用链路层例程代码(LnkTester.sln)设计实现链路层上点到点之间的通信过程,具体包括:两点之间帧同步、、差错检测、差错控制、简单的流量控制。
设计描述
本阶段主要停留在链路层对等实体之间的通信,故我们设计时出于简便的测试的想法,先不考虑上下之间的数据传递带来的封装问题,将应用层融合为链路层。不过需要修改配置文件,将PHY和APP两层的配置文件改为PHY和LNK的两层文件,主要就是改一个APP层的名字,没有其他需求印象中是不太需要改其他参数的。
1、帧结构
不管是帧、数据包还是什么其他的数据形式也好,设计之初对于帧格式的设计一定是首尾的,这是一切的基础。在计算机网络的发展史中,协议的产生常常会伴随帧格式的改变。所以这是设计中的重头戏。
PS:设计采用面向位填充首尾定界法
01111110 | 0 | 0000 | 0011001… | 0110 | 01111110 |
---|---|---|---|---|---|
帧头定界符 | ACK标志位 | 帧序号 | 数据位 | CRC校验位 | 帧尾定界符 |
2、帧定位
原理:
帧定位采用面向位填充首尾定界法。帧头和帧尾标志固定为‘01111110’,在发送方封装成帧时通过get_frame()函数将帧内连续5个1后添加一个0,以便能够准确对帧进行定位。在接收方又通过读取bit流,读到首尾的“01111110”来进行定界,然后去除数据位中的连续5个1后的0.来还原真实数据位。(U8类型=char类型,此处这样定义,只是为了专门区别,用来表示单字节数据,这是指导书的说明,但我自己使用的时候则感觉多把他看成是1bit数据的形式。)
涉及函数:
int get_frame(U8* s, int len); //发送端成帧
int locate_frame(U8* s, int len,U8* bufSend); //接收端提取帧
要点:
- 需要对于连续8位数据的读取,判断首尾定界符,这是简单的for循环。
- 需要添加和提取5个1后面的0,这也是数据结构中基础的移位问题,要注意数据前移和后移时的到底是尾部先移动还是头部先移动。
- 除了简单的去除5个1后的0,可能要考虑因为去除CRC,ACK标志位和序列号时指针头的移动和len的变化问题,也可以简单在向上层转发函数中考虑。
3、差错检测
原理:
差错检测采用CRC-4来产生校验码紧跟数据后面,其中CRC生成多项式采用固定G[5] = { 1,0,0,1,1 }利用crccode()函数来产生四位校验码,并在接收端用crcdecode()函数进行校验。校验错误则丢弃该帧,等待重传。(此处实际情况好像是多采用检错能力更强的CRC16,此处出于简便设计和运算速度,采用最短的CRC校验码)
涉及函数:
int crccode(U8* s, int len);
//计算s的CRC校验位采用生成多项式G[5]={1,0,0,1,1}
bool crcdecode(U8* s, int len); //接收方校验数据
要点:
- 添加和删除校验码的移位问题,以及注意改变数据的长度len
- CRC的计算原理是采用模2除法,区别于二进制除法
4、差错控制
原理:
对于数据在信道上进行传输的过程中可能产生的误码进行差错控制设计,我们采用停等协议进行差错控制(虽然后续阶段的设计发现,停等协议这种一发一收的方式还是不够高效,但设计是最简单的,其实可以尝试滑窗的GB_N和SR协议),增加1位ACK标识符和4位序列(由于是停等协议序号只有0000和1111),ACK标志位判断当前帧是数据帧(0)还是确认帧(1),并且判断收到的是否为正确序号的帧(相应确认帧序号总是为期待收到的下一帧的序列号)。确认帧的数据位采用八位全1(11111111)作为数据部分。为提高效率,收方收到ACK为1的帧数据位中判断收到数据位中有超过四个1即判断收到确认帧;同时序号中有三个及三个以上相同数字的即自动纠错判断帧序号。在发生差错和丢包时,利用Timeout()内部的重传函数将缓存下来的数据进行定时帧重传,直到接收到正确的确认帧,然后计时器开始变量isTimeStart停止。
涉及函数:
int add_ack_seq(U8* s, int len);
//加入1位ACK标识位和4位序列号——————确认帧的ACK为1,并且ACK的数据bit流部分为11111111
bool isAck(U8* s); //判断是否为确认帧
int get_ack_frame(U8* s, U8* ack_frame);
//生成s对应的确认帧(帧序号为期待下一次接收到的帧序号)---------------------重要变量-----------------------------超时重传--
int TickTack = 0;//全局变量在Timeout()用来差错控制中的重传
bool isTimerStart = false;//全局计时器启动标志--缓存区--
U8* buffer = NULL;//全局的缓冲区,发送前用来装载可能重传的数据
int buflen = 0;//缓冲区储存的字符串长度--帧序号--
U8 SEQ[4] = { 0,0,0,0 };//四位序列号为全局变量,只有0000和1111,停等协议中异或交替出现
要点:
- 在数据位头部,添加ACK标志位和帧序号涉及到的移位和len变化
- 帧序号由于是采用停等协议,故异或用1111和0000两个序号足矣,并且多位数据可以采用前向纠错(和数据位8位全1能够前向纠错同理),减少重传次数,提高传输效率;虽然停等协议效率本来就很低。
- 缓存区的全局变量在清空的时候建议采用提前分配一块较大的空间,然后不要采用free()释放的方式表示某次数据的缓存清空,而采用buflen=0长度清0来表示。因为在实测过程中因为前后次传输数据过程中,可能会由于超时时间的数值过小,导致出现连续多次释放同一块空间,导致以下报错。(而且反复申请和反复清空的操作本身就是一种很费资源的方式,参考数据栈清空时是因为真的不会再用那一块数据了,才清空的)。
报错截图:(这个困扰了我很久,网上只知道是释放了空内存,后来花费很久才找到上面的解决办法)
5、流量控制
在本例中,对于停等协议来说其实流量控制的意义不大,因为一发一收的机制本身就不会出现流量一股脑全怼进去的情况。但还是可以做流量控制,可以仿照重传,在Timeout()函数中设置一个阈值,和一个类似Ticktack的时钟变量,然后当达到阈值的时候,在sendtolower()前sleep一定的时间,达到流量控制的效果。(由于当时有点摸鱼,只随手写了个sleep,上面的说法才应该是正确的流控)
6、长帧传输——分片
这是当时自己没有做的一项拓展功能,但在后面传输图片或者文件的功能实现中,发现这是极其必要的。因为如果传输的数据过长,会导致数据产生错误而重传的概率提高,可能导致反复重传而传不过去。因此将数据进行分片多次传输,减小每次传输的帧长度,就有必要了。
虽然没有具体实现,但后续想了一下实现思路,还是比较简单:可以将数据按定长分段存入一个循环队列中,然后对每个小帧进行帧头和帧长的记录,然后依次封装发送。可以用一个标志变量记录当发送总数据量等于从上层接收到的帧长的时候,来表示一个完整的帧已经传输成功;或者可以用更多的帧序号加以区分。接收方则需要按帧序号重新组装数据放入一个新的内存即可。
测试情况
1、点到点数据传输情况
发送方:
接收方:
2、重传情况
发送方:
接收方:
其他想说的话
阶段二应该是后面两个阶段的基础,个人觉得阶段二主要是学会如何阅读源码,然后学会如何使用已有的一些例程函数,去方便我们的代码编写。(然后在调试过程中,最重要的就是学会看内存数据的变化,这是很重要的一点,能提高解决bug的效率)
不过好在这一阶段的代码,有老师的讲解视频可以参考,所以学着参考视频,放开手大胆去做,克服畏难情绪,好的结果才能回应这样一个好的开端!
计算机网络项目——最小网元设计(阶段二)相关推荐
- 计算机网络项目——最小网元设计(前情提要和项目概述)
目录 序言 项目总览 一.设计主题 二.阶段目标 其他想说的话 序言 经过此学期的计算机通信网挑战课程,我算是体会到了什么叫做忙碌.想着本学期已经结束,闲暇时间来整理一下本学期计通网做的大项目,或是想 ...
- 计算机网络项目——最小网元设计(阶段一)
目录 阶段目标 模型设计 功能设计 应用层 网络层 数据链路层 物理层 其他想说的话 阶段目标 完成最小网元的层次模型设计 模型设计 仿照实际应用较为更广泛的TCP/IP模型,针对本项目的最小网元,初 ...
- 计算机网络项目——最小网元设计(阶段三)
目录 阶段目标 设计描述 1.帧结构 2.按目的转发 3.反向地址学习 4.未知广播 测试情况 其他想说的话 阶段目标 本阶段主要完成链路层交换机的功能实现:单播目的地址判收.支持广播.有端口地址表. ...
- 计算机网络项目——最小网元设计(阶段四)
目录 阶段目标 设计描述 1.实体编址 2.路由表设计 3.路由配置 4.路由器的存储转发 5.端到端的图片传输 测试情况 其他想说的话 阶段目标 本阶段需要对实体进行编址,实现NET层的IP地址到M ...
- 最小网元设计【阶段零】
阶段零:序言 项目预期 设计具有多层结构的网元,并将多个网元构成一个网络,实现信息.文件在多个网元之间的传递.并利用网元搭建混合组网,实现信息在多个网元之间的收发. 阶段性目标 阶段一:设计 设计分层 ...
- 记一次计通项目(网元设计)(更新中)
我什么都不懂突然要让我写个套接字程序我当然是拒绝的,但是没有办法还是只有靠百度了. 一 首先是要学习套接字基础.一开始是照着书上写,结果书上是linux,编译不过也不知道为什么,以为我头文件漏了.百度 ...
- 【STM32】【C】【嵌入式】分享一下我的项目经验--基于stm32桌面主从机械臂设计(二弹)
本文为原创文章,转载需要注明转载出处 前言:嵌入式开发是相比其他IT行业是比较难的行业,它不仅需要你去掌握软件的经验,还要去学习一些硬件的知识, 它是软件和硬件的一个粘合剂,起到一个至关重要的地位 下 ...
- 视频教程-python项目之学员CRM管理系统开发阶段二-Python
python项目之学员CRM管理系统开发阶段二 TriAquae开源运维软件创始人,混迹IT运维领域多年,曾就职于松下.国政通.飞信.中金.NOKIA等公司,维护过少至几十台,多至数万台设备的IT系统 ...
- python项目之学员CRM管理系统开发阶段二-李杰-专题视频课程
python项目之学员CRM管理系统开发阶段二-3394人已学习 课程介绍 面向初级开发一套含有角色,权限,内容为一体的学员管理,抛弃传统的每个页面繁琐的增删改查,开发公共组件,使得开 ...
最新文章
- 酸奶饮料新产品口味测试研究案例
- 蓝鸥Unity开发基础——Switch语句学习笔记
- connect连接oracle6,Oracle Connect By 使用实例
- 我是怎么保存公众号历史文章合集到本地的?当然是用python了!
- 让Entity Framework支持MySql数据库
- 2021HDU多校8 - 7059 Counting Stars(线段树)
- quick-cocos2d-x for mac开发环境安装配置
- QLabel 图片大小设定
- 大数据分析引擎Apache Flink升级成为Apache顶级项目
- 如何用iMazing备份和恢复辐射避难所(附工具下载)
- Linux小技巧:生成随机字符串
- JavaWeb宿舍管理系统环境搭建运行教程
- 短视频后期要做哪些内容?注意细节才能做出优质短视频
- 基于深度学习的移动网络异常检测
- 定积分(黎曼和)的编程实现(java和python实现)
- 江西理工大学计算机网络基础试卷,无线网络技术作业(江西理工大学期末复习)...
- 使用 logrotate 配置 supervisor 进行日志管理按天备份
- 红队快速打点工具(POC bomber)
- Django中的跨域解决办法 基于后端的跨域解决方案
- java 写的星际争霸_用java写星际争霸的ai
热门文章
- matplotlib与seaborn的一些使用
- 图像变换dpi(tif->jpg),直方图均衡化,腐蚀膨胀,分水岭,模板匹配,直线检测
- CompletableFuture详解~思维导图
- Freemarker静态化页面的使用
- CMU本科计算机科学,CMU计算机科学学院本科难录吗?
- 加油站都需要什么手续_农村买房过户都需要什么手续?
- python字符串筛选输出_如何在Python中过滤字符串列表
- 设置同时上内外网+文件共享
- JAVA中vector是否存在数据_如何找出std :: vector中是否存在项目?
- sonar 代理_Sonar