CRC校验——某ATS协议悖论讨论

卡斯柯的ATS系统,协议接口都有,应该不是秘密。

要做一个服务器,接收ATS信息,转发,不过做接收DEMO的时候遇到点小问题。

 

贴一下原协议:

 

第一张图是5秒一次的行车信息。

 

第二张图是不定时的进出正线信息(也就是上线,开始运营,或者下线,休整)

 

 

位置比较固定,作用比较关键的是header,length,message_flag和CRC。

第一个是协议头,第二个是“长度”(不是真长度,是他后边的数据域的长度,不包括CRC,总之比较绕的计算方式),第三个是类型,这不是两种协议包吗?判断用的,最后那个就是校验了。

 

 

第三张图是收到信息对ATS的反馈

 

 

因为ATS每五秒发送一次所有列车的行车信息,有列车变轨(进出正线)时发送一次进出正线信息,列车数量大概120辆。

ATS协议行车信息包大小:8bytes+15*nbytes,不知道他们对0列车是怎么定义的,总之,1列车是23,2列车是38,以此类推。。。

ATS协议进出正线信息包大小:17bytes

 

看起来是很平淡的信息量,不过还是脑洞大开,考虑一些极端情况:假设,在极微小的read()间隙,刚好在行车信息之间出现了进出正线信息。又或者进出正线信息在行车信息之前出现。总之就是缓冲区堆积上了,这样read()就是多条协议包。然后这样就做个游标,读出数据后遍历一下,这个遍历是根据协议内部的长度信息进行相应的移动来完成的,需要对ATS协议有一定了解(读来读去多读几遍呗),总之不是特别难。

 

因为协议有CRC校验,而之前他写的什么ISO3309之类的我不懂,就搁置了,处理逻辑做完了就做CRC校验,一做,脑洞更大了。之前的DEMO假设数据都正确了,现在加上CRC校验,就考虑数据不正确怎么办?如果数据不正确,那么用以判断协议长度的变量也就不正确,也就不知道协议的边缘在哪。不知道协议的边缘在哪,意味着一次read出现一个CRC校验错误后,后边的信息都废了。

 

遂去找人讨论,一讨论,问题更恶心了,“数据太多,一次读不出来你怎么办?你接到的不一定就是头部!”

这个确实没法解,通过协议头吗?协议头内容为0xa0a0,但是协议头就一定对吗?校验了吗?而且包内数据里就不能恰好有0xa0a0吗?所以也不能就拿0xa0a0来确认协议头在哪吧?

 

另外,反馈确认信息只有一个头部0xb0b0,这缓冲区堆积情况明显就不在考虑范围之内,有两条数据都区分不开到底是对哪条信息的确认,别说多的数不清的数据包了。区分开了又有什么用,按目前的理解,ATS只管自顾自的发信息,没什么互动。

 

最后,说CRC也不是确保无错的,CRC都错了怎么办?

 

目前只能顺其自然,最起码我加了头部判定和协议类型判定,还有CRC,一切错误数据都是纸老虎——被弃置,看人家5秒发一次行车信息,甚至还说“没有进出站等关键信息收到行车信息DDS也不进行转发”,所以是容许一定的时间误差的。另外加大read()频率(本来就很快)和加大用来read()的buffer应该都是有效途径。

 

 

 

但是问题终究是要解决的,别人的压力大的服务器又都是如何处理的,也许别的协议更健壮?而这个ATS协议不行?

还有系统机制问题——缓冲区到底有多大,存多少数据?我接收buffer可以设置和它一样大从而一次接收完成吗?

 

 

最新悖论

因为不定长,CRC位置必须依靠length变量推测,而不先校验CRC,又怎能确定length值无误?

所以,舍弃错误数据才是王道,或利用读取速度优势靠时间消磨,或直接调用系统调用(暂时我也不知道具体是哪个调用,fflush()之类?待查!)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值