zoukankan      html  css  js  c++  java
  • 底层通信协议的设计流程

    ref : 底层通信协议的设计

    背景

    对于很多设备之间的通信,经常需要自己设计一套通信协议。当然此处的通信协议一般都是建立在TCP/IP协议等协议基础之上的协议,也就是在已有协议的基础之上,在定义一套协议。例如:有一套检测降雨量的设备(一般为简单的嵌入式设备)需要把采集到的的数据上报给中心服务器(一般为一台性能特别好的计算机)。就需要一套通信协议。以保证,嵌入式设备上发的数据,可以被中心服务器正确的理解和处理。再例如:在桥梁检测的项目中,会检测很多桥梁的数据,应力,索力,温度等,这些检测设备一般都是由简单的传感器组成的嵌入式设备 ,需要通过各种方式把采集到的的数据上报给中心服务器,中心服务器经过分析处理后,再进一步判断桥梁的各种状态。这些都涉及到自定义通信协议。

    但这些自定义通信协议如何设计?有设计到那些方面?

    协议的设计:是为了保证双方能够正常的通信,由于上位设备和下位设备一般是不同的设备,处理能力有很大差异,这些都是设计协议必须考虑的问题。

    协议的构成部分

    一套完整的协议,通常包含很多命令,每一个命令都会规定一个完整的命令(也就是一个完整的数据帧)包含哪些部分,一般包含以下几部分:

    • 数据帧的组成的形式: 一般形式有字节流(有的地方也叫做二进制协议)和字符流。字节流一般会规定每一个字节表示的含义,而字符流由于都是可见的字符,一般会规定,字符的含义。
    • 数据帧头和尾:

    数据帧头和尾其实是为了解析数据而设计的,主要是为了获取一个完整的帧。由于网络的不确定性,无法保证一条完整的数据帧的一次性就发送给对方。一般选择用很少出现的字节或者字符作为数据帧头和尾。

    例如我曾经解析过得MODE 04 PROTOCOL的一套协议,就是以0x03,0x14开头的,由于MODE 04 PROTOCOL是字节流协议,因此规定了命令的开头两个字节是0x03,0x14,还曾经解析过字符流的协议,命令是以##开头。数据帧尾有时会有,有时没有,例如MODE 04 PROTOCOL就没有协议尾,因为它有两个字节表示本条数据帧的长度,所以没必要规定数据帧尾。相反,如果无法判断一条命令的长度,就会规定数据帧如何结束。如果数据帧长度都是一样的,也没有必要规定,但实际中很少遇到数据帧长度是固定的情况。

    • 数据帧的验证部分:对于字节流的协议,一般会规定验证数据帧的验证部分,例如MODE 04 PROTOCOL就规定了数据帧最后两个字节是crc验证部分。对于字符流的也可以加验证字段,但因为每一部分都都是可视的字符,也可以不加。

    • 转义字符: 再少出现的字符由于数据帧内容的不确定性,也有可能在数据帧内部出现,例如:MODE 04 PROTOCOL协议当数据帧内部出现了0x03,0x14,也就是数据帧规定的开始部分,就必须转义,否则就会解析出错。导致一个数据帧变成两部分不完整无法理解的数据帧。

    • 命令字及其他: 命令字就是标示此数据帧,需要完成的命令,例如:读取时间命令数据帧,就有一部分标示此数据帧是读取时间,设置时间命令数据帧就有一部分标示此数据帧是用来设置时间的,当然会有命令内容例如把时间调整到多少。

    • 心跳包: 心跳包作为一条很特殊的数据帧,作用其实和人的心跳类似。每隔一段时间,就会发送一条很特殊的数据帧心跳包。作用就是表明此设备还在工作。

    例如QQ的在上状态应该就是通过类似心跳包的设计来完成的。但在无线领域还有其他作用,避免已经建立的链接断开。尤其数据是通过GPRS发送时,如果长时间不发送数据,网络运营商就会回收链接,下次发送数据时,就必须重新建立链接,这对于需要永远在线的设备或者是需要随时唤醒的设备来说,显然是不行的。

    对比

    字节流协议难度显然比字符流大很多,解析过程也更复杂,如果没有协议文档,几乎不能解析,因为收到的就是一串毫无意思的数字,一个字节处理错误就完全可能导致整条数据解析错误,此外字节流还需要规定大端模式和小端模式等。当然好处就是,传输同样的信息,数据量明显少很多。

    字符流就简单很多,解析的过程可能就是一个正则表达式。

    协议设计

    当需要进行网络通讯时,要想让双方识别对方,就涉及对协议的设计。那么 在具体项目中,如何设计协议呢?或者如何设计出较高效的协议?来满足项目的 要求呢?

    一般来说,一个基本的数据包协议需要以下部分

    1. 协议的标识

    2. 协议版本号

    3. 协议包的序号

    4. 协议包的发出时间

    5. 协议包的类型

    -------------------

    6. 协议包的数据长度

    7. 数据

    -------------------

    8. 校验码

    9. 结束符

    上面的9点中,第一个横线上的是包头部分,对于每个数据包都是 一样的,但对于后面的6,7跟具体的包有关,这部分是不同的。 下面的8.9也是相同的。

    协议包的数据长度 与 数据

    下面继续说明6, 7两点的设计办法。

    如果协议包的每种类型下面没有更多的分类,那么,数据这部分无需再设计 只要一个值即可,但情况往往不是那么简单,情况如下:
    1)如果数据也有多种类型,那么数据部分得再加上一个类型标号
    2)如果数据同时有多个,那么数据部分必须分成二部分,一部分表明其数据 个数,后面再跟多个数据个体。

    对于MD5加密,它是对任意长的字节串进行运算,产生一定长的大整数, 它的长度是32个字节,128位。 MD5广泛用在数字签名中,及用户验证中 数字签名的应用比如,在下载时,会附带一个.md5,里面有一个32个字符, 这就是此下载文件的md5值, 下载者可将此文件进行md5运算,看其值是否等于.md5里的内容。

    用户验证的例子比如. 将登录名计算成一个md5大整数, 当用户登录时,将此时的登录名用md5算法运算一下,看其值与md5是否相等。

    ---------------------------------

    例子:设计一个传递室内温度,与 空气含氧量的协议

    首先 1, 2, 3, 4, 点好设计,照搬即可, 那么5的类型,此处有二个,即温度或 者空气含氧量, 其类型有二种0xC1, 0xC2

    6数据的长度与7数据内容有关,7数据内容可以是获取温度时间与温度值, 也可以是获取时间与空气含氧量。

    8, 9 照搬即可。

  • 相关阅读:
    利用FormData对象实现AJAX文件上传功能及后端实现
    $.ajax not function(已 解决:jQuery库冲突解决办法)
    什么是docx,pptx等的正确MIME类型?
    session_end
    cookies.Expires (小技巧)
    如何生成静态页面的五种方案(转)
    Request.UserHostAddress和Request.Url.Host(小技巧)
    单点登录的一些实现
    框架页的session和cookies
    在IHttpHandler使用session
  • 原文地址:https://www.cnblogs.com/schips/p/12557027.html
Copyright © 2011-2022 走看看