版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

本文链接:https://www.cnblogs.com/lihuidashen/p/12800323.html

微信链接:https://mp.weixin.qq.com/s/LMBklt3xyZR2mu076lguCg

最近在做无线传输的通信协议实现,这里涉及到超时重传,窗口移动,可靠性传输的问题,有些一些心得,也有很多的调试历程,与大家分享,当然源码不会开源,但是思想会毫无保留.

首先我们看重传原理ARQ

ARQ(AutomaticRepeat reQuest,自动重传请求)是在数据链路层(MAC)实现的一种可靠性传输机制。其重传原理是发送端先将数据链路层的数据SDU按照固定的ARQ块大小来进行分片,最后剩下的数据不管多小都分为一个分片,接着为每个分片进行编号BSN(Block Sequence Number),如下图所示:

ARQ机制中SDU分片和BSN示意图

随后确定发送端的ARQ滑窗,即:将第一个发送PDU块作为ARQ发送窗口的起始PDU块ARQ_TX_WINDOW_START,接下来发送的下一个PDU块作为ARQ发送下一个PDU块ARQ_TX_NEXT_BSN。当发送的1个或N个PDU块被接收端确认接收成功后,其滑窗的起始PDU块ARQ_TX_WINDOW_START会加1或N,即:往后面滑1或N格,而下一个PDU块始终指到未发送PDU块的第1个。

同时,接收端也会根据接收情况来确定接收ARQ滑窗,即:通过ARQ接收起始PDU块ARQ_RX_WINDOW_START和接收ARQ滑窗大小ARQ_RX_WINDOW_SIZE两个参数来确定该滑窗大小。当在滑窗内的PDU块全部接收到后,会确认这次接收PDU的结果,如果有个别PDU块接收失败,则在后续的反馈IE中指出来,让发送端进行重传,重传最大次数来控制重传次数,否则就直接将接收ARQ滑窗往后滑,ARQ接收起始PDU块ARQ_RX_WINDOW_START会滑到还未接收PDU块的第1个,整个滑窗整体往后滑动。

以上的传输过程请参考下图:

ARQ传输机制原理图

那么怎么实现呢?

对于单个数据包来说,是很简单的,其ARQ状态机如下

对于需要窗口传输的重传机制来说,如图所示,

发送窗口只有收到对端对于本段发送窗口内字节的ACK确认,才会移动发送窗口的左边界。
    接收端可以根据自己的状况通告窗口大小,从而控制发送端的接收,进行流量控制。

我们来定义数据结构

//数据索引typedef struct {  int status;  int dataID;  u16* Recvbuffer;  int len;}CommDataIndex;

//包的状态typedef struct{ int id; int crc;}PacketStatus;

//发送状态typedef struct{ int dataID; int iRetries; int iResendTimerID;//重传定时器 int iCycleTimerID; //生命周期定时器
}SendStatus;

//窗口信息typedef struct { int winSize; SendStatus status[wSize]; int minID; int maxID;
}WINMSG;

//数据类型enum{ RTS=0, CTS,
ACKNAK, payload,
}DATATYPE;

数据结构定义如下图,当有数据需要发送时,先申请动态内存缓存数据,最多缓存20包数据,数据的具体内容如CommDataIndex中所示,包含数据ID序号、数据buffer、数据长度;窗口的内容(包含窗口大小,窗口中每包数据发送状态,窗口中最小最大的数据ID序号) 如winMsg所示;数据包发送状态(包含数据ID,重发次数,重发定时器,生命周期定时器)如下Status所示。

发送端具体流程:

有数据发送时,先判断CommDataIndex数组中是否有空的位置,如果为空则将数据放入,最多缓存20包数据;

判断窗口是否满状态,当窗口不是满状态时,则可以发送数据,更新窗口信息(窗口中的最小最大ID,发送状态),启动发送状态中的定时器、更新重传次数;

当返回ack,则表示发送成功,判断是哪一包发送成功,找到这一包在commDataIndex的位置,并且清空,释放内存,找到这一包在窗口中的位置,清除这个位置窗口的发送状态信息(重传次数,数据ID),关闭这个窗口位置的定时器;如果这一包是窗口中最小的ID值,则可以移动窗口,进行下一包的传输,更新窗口中最小最大ID值

当返回nak,则表示发送失败,判断是哪一包发送失败,找到这一包在winMsg的位置,关闭窗口中对应的定时器,此时进行重发,更新发送状态status,更新重传次数,并且开启窗口中对应的定时器;当重传次数超过4次时,关闭对应的定时器,清空窗口发送状态的信息,重传次数,数据ID,找到这一包在commDataIndex的位置,并且清空,释放内存。

当没有响应消息时,表示发送超时,窗口对应的定时器ID构造事件传递给通信任务的定时器事件接收ID中,在发送端事件ID中处理,首先关闭定时器,找到定时器对应的窗口的位置,更新对应窗口发送状态信息,更新重传次数,当重传次数超过4次时,关闭对应的定时器,清空窗口发送状态的信息,重传次数,数据ID。进行重传操作,并且启动定时器。

当数据发送时长到达重传生命周期定时器限值时,表示整包数据没有在规定的时间里发送成功,此时关闭对应窗口的定时器,清空对应的窗口信息以及这一包数据的缓存信息,如果此时发现缓存数据中有数据需要发送,则进行发送,更新对应的窗口信息。

结果查看

 

推荐阅读

(点击标题可跳转阅读)

【编程之美】用C语言实现状态机(实用)

【超详细C语言】带你吃透贪吃蛇游戏之精髓

【编程之美】超时重传,滑动窗口,可靠性传输原理C语言实现的更多相关文章

  1. 【编程之美】常用于单片机的接口适配器模式C语言实现

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://www.cnblogs.com/lihuidashen/p/128750 ...

  2. 7、滑动窗口套路算法框架——Go语言版

    前情提示:Go语言学习者.本文参考https://labuladong.gitee.io/algo,代码自己参考抒写,若有不妥之处,感谢指正 关于golang算法文章,为了便于下载和整理,都已开源放在 ...

  3. TCP面试题之滑动窗口原理

    TCP 滑动窗口 作用: 1. 提供TCP可靠性:对发送的数据进行确认 2. 流量控制:窗口大小随链路变化 一.TCP窗口机制 TCP中窗口大小是指tcp协议一次传输多少个数据.因为TCP是一个面向连 ...

  4. [TCP/IP] 滑动窗口

    什么是滑动窗口? 滑动窗口机制是TCP协议的一种流量控制和防拥塞的机制. 滑动窗口的工作原理? 简单来讲,就是接收方和发送方分别保留一块缓冲区,作为接收和发送数据来使用,发送数据过程中,如果发送方发的 ...

  5. 彻底搞通TCP滑动窗口

    在我们当初学习网络编程的时候,都接触过TCP,在TCP中,对于数据传输有各种策略,比如滑动窗口.拥塞窗口机制,又比如慢启动.快速恢复.拥塞避免等.通过本文,我们将了解滑动窗口在TCP中是如何使用的. ...

  6. storm 1.0版本滑动窗口的实现及原理

    滑动窗口在监控和统计应用的场景比较广泛,比如每隔一段时间(10s)统计最近30s的请求量或者异常次数,根据请求或者异常次数采取相应措施.在storm1.0版本之前,没有提供关于滑动窗口的实现,需要开发 ...

  7. 源码分析 Alibaba sentinel 滑动窗口实现原理(文末附原理图)

    要实现限流.熔断等功能,首先要解决的问题是如何实时采集服务(资源)调用信息.例如将某一个接口设置的限流阔值 1W/tps,那首先如何判断当前的 TPS 是多少?Alibaba Sentinel 采用滑 ...

  8. TCP超时重传、滑动窗口、拥塞控制、快重传和快恢复

    TCP超时重传 原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止. 影响超时重传机制协议效率的一个关键参数是重传超时时 ...

  9. TCP协议可靠性是如何保证之滑动窗口,超时重发,序列号确认应答信号

    原创文章首发于公众号:「码农富哥」,欢迎收藏和关注,如转载请注明出处! TCP 是一种提供可靠性交付的协议. 也就是说,通过 TCP 连接传输的数据,无差错.不丢失.不重复.并且按序到达. 但是在网络 ...

随机推荐

  1. GCDAsyncSocket 笔记

    https://www.dzliving.com/2019/03/26/gcdasyncsocket-%E7%9A%84%E5%B0%81%E8%A3%85%E4%B8%8E%E4%BD%BF%E7% ...

  2. centos7中安装mysql

    centos7中安装mysql网上已经很多资源了,我就不在赘述了.我这里只是记录下我安装的时候出现的一些问题. 原文:https://www.cnblogs.com/bigbrotherer/p/72 ...

  3. 商品spu 和 sku的关系

    总结一下在目前的电商系统中的商品涉及的属性spu,sku.搞清楚两者之间的关系对表的设计非常重要 spu Standard Product Unit (标准产品单位) ,一组具有共同属性的商品集 SK ...

  4. Vue 【前端面试题】

    前言 看看面试题,只是为了查漏补缺,看看自己那些方面还不懂.切记不要以为背了面试题,就万事大吉了,最好是理解背后的原理,这样面试的时候才能侃侃而谈.不然,稍微有水平的面试官一看就能看出,是否有真才实学 ...

  5. 性能测试环境搭建:XAMPP1.8+PHPwind9.0安装教程

    1.安装准备 1.1软件版本 XAMPP的版本:XAMPP 1.8.2 phpwind的版本:PHPWind 9.0   1.2.安装环境 我的环境:win10 其实安装环境影响不大,win7,win ...

  6. L - Subway(最短路spfa)

    L - Subway(最短路spfa) You have just moved from a quiet Waterloo neighbourhood to a big, noisy city. In ...

  7. 基于Quartz编写一个可复用的分布式调度任务管理WebUI组件

    前提 创业小团队,无论选择任何方案,都优先考虑节省成本.关于分布式定时调度框架,成熟的候选方案有XXL-JOB.Easy Scheduler.Light Task Scheduler和Elastic ...

  8. LeetCode | 136. 只出现一次的数字Ⅰ Ⅱ

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1: 输入: [ ...

  9. 使用Putty登录亚马逊云主机

    亚马逊云主机配置之后会提示 提供一个 pem证书, 打开 SSH 客户端.(了解操作方法 使用 PuTTY 连接) 找到您的私有密钥文件(test001.pem).向导会自动检测您用于启动实例的密钥. ...

  10. Nagios监控服务

    Nagios监控服务 案例1:常用系统监控命令 案例2:搭建nagios监控服务器 案例3:配置文件及插件使用 案例4:监控远程主机的公有数据 案例5:监控远程主机的私有数据 1 案例1:常用系统监控 ...