自定义通信协议设计基础

2024-08-24 01:32

本文主要是介绍自定义通信协议设计基础,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文转自:http://www.360doc.com/content/14/0915/11/1073512_409611008.shtml

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

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

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

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

1、数据帧的组成的形式

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

2、数据帧头和尾

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

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

3、数据帧的验证部分

对于字节流的协议,一般会规定验证数据帧的验证部分,例如MODE 04 PROTOCOL就规定了数据帧最后两个字节是crc验证部分。

对于字符流的也可以加验证字段,但因为每一部分都都是可视的字符,也可以不加。

4、转义字符

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

5、命令字及其他

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


6、心跳包

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

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

对比:

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

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


这篇关于自定义通信协议设计基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1101066

相关文章

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

SpringBoot自定义注解如何解决公共字段填充问题

《SpringBoot自定义注解如何解决公共字段填充问题》本文介绍了在系统开发中,如何使用AOP切面编程实现公共字段自动填充的功能,从而简化代码,通过自定义注解和切面类,可以统一处理创建时间和修改时间... 目录1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应