温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

自制应用层协议的编写

发布时间:2020-08-20 22:07:10 阅读:1280 作者:tangyouyi1513 栏目:移动开发
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

                                              

近日编写了一个手机的灯控系统:

  自制应用层协议的编写             自制应用层协议的编写         自制应用层协议的编写

因为添加了许多以前不具备的功能,并且为了数据传输更加稳定,格式更加规范,并且为了以后再进行同类项目的格式统一,本次特地根据计算机网络,在已有的协议HipulseU基础上进一步改造,自制了一套应用层的协议。

首先本套协议的格式定义如下:

协议格式:

SOI 7EH 起始位标志 1字节   ASCII:  7EH

VER 10H            1字节    ASCII: 31H,30H

ADR 01H            1字节    ASCII:30H,31H

CID1 命令 41H  运行控制命令

           42H 配置文件读写命令

           43H 时钟控制命令

           44H EEPROM命令

           45H 写文件名

CID2 辅助命令       1字节

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

           CID1=41H 运行命令

                CID2:

                 10H:参数配置信息n每条14字节HEX(28字节ASCII

                 13H:参数运行EEPROM中的配置信息开机缺省。

                 14H: 参数运行CID1=45H中指定的文件。

                 20H:停止命令

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

           CID1=42H 写配置文件

                CID2:

                 00H:~FEH 写配置文件

                 FFH    写配置文件,续写配置文件结束

           CID1=43H:时钟 

                CID2:

                 00H:写时钟命令格式: ---星期--- (分别为两个字节ASCII)

                 01H:读时钟命令格式: ---星期---

                 02H:设置开机关机时间 

                                           

                      格式 开始:(年---参数---秒)

                            结束:(年---参数---秒) 

                     

                      参数:两字节ASCII                             

D7       D6       D5        D4        D3       D2        D1        D0

0         1         1         1          1        1         1          1  

    星期                                              

1         0         0        0         0         0         0         0

年月日十分秒

1         1         1

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

           CID1=44HEEPROM写配置信息

                CID2:

                 00H:向EEPROM写配置信息

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

           CID1=45H:文件名  

                CID2:

                 00H:文件名(写入或运行的文件名,1字节)

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

           CID1=46H:预览设置

                CID2: 

                 00H: 1

                 01H: 10

                 02H:100

                 03H:1000

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

      LENGTH  2字节长度 先传高字节再传低字节

      其中:校验码:LCHKSUM=D15~D12 

            长度标示码:LENID=D11~D0 表示INFO中传送的ASCII码字节数

            校验码计算:D11~D8+D7~D4+D3~D0,求和后模16余数取反加1

INFO数据格式

      COMMAND INFO

CHKSUM数据格式

    CHKSUM的计算是除SOI,EOICHKSUM外,其它字符按ASCII码值累加求和,所得结果模65536余数取反加1

      

EOI 0DH 结束码

响应信息

SOI 7EH 起始位标志 1字节   ASCII:  7EH

VER 10H            1字节    ASCII: 31H,30H

ADR 01H            1字节    ASCII:30H,31H

CID1 60H

CID2 RTN    

LENGTH 2字节长度 先传高字节再传低字节

      其中:校验码:LCHKSUM=D15~D12 

            长度标示码:LENID=D11~D0 表示INFO中传送的ASCII码字节数

            校验码计算:D11~D8+D7~D4+D3~D0,求和后模16余数取反加1

INFO数据格式

      DATA INFO

CHKSUM数据格式

    CHKSUM的计算是除SOI,EOICHKSUM外,其它字符按ASCII码值累加求和,所得结果模65536余数取反加1

EOI 0DH 结束码

RTN:

00:正常

 01VER

 02CHKSUM

 03LCHKSUM

 04: CID2无效

 05:命令格式错

 06:无效命令

 E0:地址错

 E1~EFH:其它错误

 12H:参数文件名 文件中存配置文件名每个配置文件名1字节(ASCII两字节)

 11H:参数文件名  每个1字节(两字节ASCII码)

协议中的所有内容都是把一字节的内容,用两字节的ascii码来替换,例如原本的内容是一字节0x2f,最终会被替换为

0x32 0x46(2的ascii码是0x32,f的ascii码是0x46)

由于本次使用的是Android编程所以最终协议被封装成java包,

首先定义数据格式类把要传输的数据定义为Data类:

public class Data {private byte[] sol;private byte[] eol;private byte[] ver;private byte[] adr;private byte[] cid1;private byte[] cid2;private byte[] lenid;private byte[] info;private byte[] chksum;
        //以下定义Data类的各个数据成员变量的getter和setter方法
}

再定义一个DataOperator类用对,Data类进行各种操作。

由于要进行十六进制代码与ascii码之间的转换所以,要创建一个静态数组来进行两者的对应:

public class Ascii {
public static byte[] ASCII = new byte[] { 0x300x310x320x330x34,
0x350x360x370x380x390x410x420x430x440x450x46 };
}

下面主要介绍  LCHKSUM的计算方法和CHKSUN的计算方法:

下面是LCHKSUM的计算方法,该方法通过对相应的LENGTH内容进行构造LCHKSUM

public byte[] createLength_chksum(byte[] src) {
byte[] result = new byte[1];
// 用来记录计算len_chksum时的中间转换变量
int len_check = 0;
// 计算len_chksum先计算长度每个字节所代表的ascii码的字符的真值和
for (int i = 0; i < 3; i++) {
if (src[i] > 0x39) {
len_check = len_check + (src[i] & 0xff) - 0x37;
} else {
len_check = len_check + (src[i] & 0xff) - 0x30;
}
}
// System.out.println(len_check);
// 把相应的和模16
len_check %= 16;
// 再把结果取反
len_check = 16 - len_check;
// 得到结果的ascii码的真值
if (len_check == 16) {
result[0] = 0;
} else {
result[0] = Ascii.ASCII[len_check];
}
// System.out.println(result[0]);
return result;
}

下面是CHKSUM的计算方法,参数为整个数据(除了开始和结束位):

public byte[] createChksum(byte[] src) {
// 用来记录计算chksum时的中间转换变量
int check = 0;
// 用来存放chksum结果
byte[] result = new byte[4];
// 计算每一字节的和
for (int i = 1; i < src.length; i++) {
// System.out.println(src[i]);
int a = src[i] & 0xff;
check = check + a;
}
System.out.println(check);
// 把和对65535求余数
check = check % 65536;
// 再把求余之后的结果取反
check = 65536 - check;
// 把最后的结果分为四字节的ascii码
result[0] = Ascii.ASCII[((check >> 12) & 0x0000000f)];
result[1] = Ascii.ASCII[((check >> 8) & 0x0000000f)];
result[2] = Ascii.ASCII[((check >> 4) & 0x0000000f)];
result[3] = Ascii.ASCII[((check & 0x0000000f))];
System.out.println(result[0] + " " + result[1] + " " + result[2] + " "
+ result[3]);
return result;
}



亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×