netty 自定义16进制 项目实战
来源:互联网 发布:社会心理学 知乎 编辑:程序博客网 时间:2024/04/30 17:19
有关netty基本知识就不在此做过多说明、大家可以baidu学习基本知识。本文给大家提供一个netty 项目实例供大家学习、也可在项目中使用。
项目说明:
用户使用手机app 下发消息给充电设备、从而达到自动给电动汽车充电、也就是现在流行的充电桩。
定义协议如下:
发送报文
域 名
字节数
说 明
起始域
1
起始字节,固定为0x68
版本
1
该版本文件固定为0x01
功能码
1
消息类型,下文做解析
充电设施ID
4
设备唯一编码
包号
1
针对需要多包传输的数据
包号起始位0x01
数据长度
2
单包数据域字节数,单包长度不超过500字节
数据
n
数据域,不同的功能码对应不同的数据定义
校验码
1
采用累积和校验,计算范围为数据域
接收报文
域 名
字节数
说 明
起始域
1
起始字节,固定为0x68
版本
1
该版本文件固定为0x01
功能码
1
消息类型,下文将详细解析
充电设施ID
4
设备唯一编码
反馈标志码
1
反馈标志码下文做解析
包号
1
针对需要多包传输的数据
数据长度
2
单包数据域字节数,单包长度不超过500字节
数据
n
数据域,不同的功能码对应不同的数据定义
校验码
1
采用累积和校验,计算范围为数据域
心跳故障码(1字节):自定义
返回错误码(1字节):自定义
具体解码编码代码如下:
解码:
// 68开头
if (hex.startsWith("68")) {
ParamInfo result = new ParamInfo();
// 设置版本号
result.setVersion(DigitalUtils.hex2Algorism(hex.substring(2, 4)));
// 设置功能码
result.setServiceName(hex.substring(4, 6));
// 设置充电桩编号(16进制转10进制,前面补0)
result.setStubId(StringUtils.leftPad(String.valueOf(DigitalUtils.hex2Algorism(hex.substring(6, 14))), 8, "0"));
// 数据索引块(包号)
result.setDataIdx(DigitalUtils.hex2Algorism(hex.substring(14, 16)));
// 数据长度
result.setDataLength(DigitalUtils.hex2Algorism(hex.substring(16, 20)));
// 数据长度检查
if (hex.length() != 20 + result.getDataLength() * 2 + 2) {
result.setErrCode("F1");
return result;
}
// 数据拆分
String dataHex = hex.substring(20, 20 + result.getDataLength() * 2);
if (result.getDataLength() > 0) {
int startIdx = 0;
List<StructInfo> structureList = ConfigUtils.getDecodeStruct().get(result.getServiceName());
if (structureList != null) {
for (StructInfo structInfo : structureList) {
result.addRequestData(structInfo.getName(), structInfo.cover(dataHex, startIdx));
startIdx = startIdx + structInfo.getLength() * 2;
}
} else {
result.setErrCode("05");
return result;
}
}
// 校验运算
String verifyString = hex.substring(20 + result.getDataLength() * 2, 20 + result.getDataLength() * 2 + 2);
if (!verifyString.equals(DigitalUtils.ADD(dataHex))) {
result.setErrCode("07");
return result;
}
return result;
}
编码:
// 起始域+版本+功能码+充电桩编号+错误位
hexSb.append("68").append("01").append(param.getServiceName()).append(param.getStubId()).append(param.getErrCode()).append("01");
List<StructInfo> structList = ConfigUtils.getEncodeStruct().get(param.getServiceName());
// 生成数据
StringBuffer dataHex = new StringBuffer();
// 有返回数据结构且是正常返回
if (structList != null && "00".equals(param.getErrCode())) {
for (StructInfo structInfo : structList) {
Object value = param.getResponseDate().get(structInfo.getName());
// TODO 不在此范围内的转型报错
if (structInfo.getType() == 1) {
// 如果返回数据类型必须为ascii
if (value instanceof String) {
dataHex.append(DigitalUtils.StringToAscii((String) value));
}
} else if (structInfo.getType() == 0) {
// 如果返回数据类型必须为hex
if (value instanceof Integer) {
dataHex.append(DigitalUtils.algorism2Hex((Integer) value, structInfo.getLength() * 2));
} else if (value instanceof BigDecimal) {
dataHex.append(DigitalUtils.algorism2Hex(((BigDecimal) value).intValue(), structInfo.getLength() * 2));
} else if (value instanceof String) {
dataHex.append(value);
}
}
}
项目架构:
spring 注解、jdbc 连接池、membercache、netty4 。因项目比较大、如需要项目源码 可联系我 qq 451366323
- netty 自定义16进制 项目实战
- Netty 实战
- netty实战-自定义解码器处理半包消息
- netty 高并发实战
- netty实战进阶
- Netty实战(精髓)pdf
- 《Netty实战》第一部分
- Ionic 3 项目实战------自定义插件
- netty实战-netty client连接池设计
- netty实战-netty client连接池设计
- Dubbo,Redis,ActiveMQ,Nginx,Netty,Jvm技术架构,大型分布式电商项目实战
- java分布式架构Dubbo+Zookeeper+ActiveMQ+Redis+Nginx+Netty+Oracle+RocketMQ+Linux,教学视频+项目实战
- Netty自定义协议开发
- netty自定义协议解码
- MessageToMessageDecoder netty自定义协议
- netty自定义协议
- netty自定义心跳机制
- 阅读Netty实战(精髓)笔记
- 使用api工具时get请求和post请求的不同
- 人脸情感识别相关的资料
- 性能检查
- Activity 重载方法 onStart和onResume、onPause和onStop的区别
- OpenCv 人脸检测的学习
- netty 自定义16进制 项目实战
- 视频读写函数
- 关于oc和js交互那点事
- 做一个企业网站需要多少钱?
- 预处理指令 #pragma 的使用
- 欢迎使用CSDN-markdown编辑器
- C++中的static关键字的总结
- Java枚举类型enum
- python 学习笔记6