我们在进行串口通信的时候,通常直接进行read write,但显然这种信息传输是不稳定的,稍微有点干扰,就有可能传输数据发生错误,如何保证稳定可靠的串口数据传输,确实是一个问题。
第一种方式,我们使用modbus,其实modbus协议本身并不可靠稳定的,但可以通过不间断读取寄存器的值来实现稳定的信息传输,例如我们的从设备每1秒刷新一次信息,主设备每200ms获取一次信息,那么就可以间接实现稳定的信息传输,但弊端也很多,首先传输的信息容量不大,没有校验,从设不能主动发送数据,需要不断的请求数据,在正常传输时会大量的浪费信道。
第二种方式,我们使用以包为单位的传输方式,就是为我们发送的每条数据进行封装,我们将一条数据称为一帧,每一帧都有自己的帧id,并可以在帧尾加上校验码,设备收到数据后并返回确认帧,这种方式解决modbus的很多问题,同时也是串口通信的主流方式,但这种方式也有弊端,就是如果一帧传输的内容过大,那么传输此帧失败的概率会直线上升,当多次重传后,也会严重占用信道,导致信道阻塞,当然这个问题可以通过分包问题解决。
第三种方式,采用ARQ协议,有的人可能对ARQ这个词比较陌生,但大家肯定都知道TCP协议,TCP协议就是ARQ的一种实现方式。
自动重传请求是OSI模型中数据链路层的错误纠正协议之一。它包括停止等待ARQ协议和连续ARQ协议,错误侦测(ErrorDetection)、正面确认(PositiveAcknowledgment)、逾时重传(RetransmissionafterTimeout)与负面确认继以重传(NegativeAcknowledgmentandRetransmission)等机制--百度百科
这时有人会想到能不能直接在串口中实现TCP传输,理论上是可以的,但TCP包头中包含IP等信息,这在串口传输中是不需要的。
在游戏开发当中,我们有时为了保证低延迟并不使用TCP,而是使用UDP进行通讯,但UDP的弊端也很明显,UDP是不可靠的,这时在UDP的基础上进行可靠通讯需求便应运而生,这也是我们接下来要介绍的KCP通讯。
KCP是一个快速可靠协议,能以比 TCP 浪费 10%-20% 的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据包的发送方式,以 callback的方式提供给 KCP。 连时钟都需要外部传递进来,内部不会有任何一次系统调用--kcp简介
我们从简介中可得知,kcp只负责算法实现,并不负责其他。这就为我们的串口通信提供了一种比较契合的通信方式。同时浪费带宽这个问题我们其实可以忽略不计,配置好流量控制即可。
下章会使用c++ qt实现kcp串口。