dtu tcp java_SpringBoot 2 整合 Netty 实现基于 DTU 的 TCP 服务器 之 客户端

本文介绍了如何使用SpringBoot 2.1.4与Netty构建一个基于DTU的TCP客户端,以进行数据收发。在DTU协议基础上,通过字节数组的编解码处理解决半包、粘包问题。首先,引入Netty相关依赖,接着实现字节数组的解码器ByteArrayDecoder和编码器ByteArrayEncoder,确保与C语言的DTU设备兼容。然后,创建客户端启动类NettyClient,建立与服务器的连接,并处理登录及心跳维持。最后,通过Handler类处理登录响应和心跳消息。
摘要由CSDN通过智能技术生成

6d0e72737ab6

使用netty不是一天两天了,但是使用netty和DTU通讯还是第一次,接下来要做DTU的通讯协议,对接工作还没有正式开始,只收到一个简单的DTU协议文档,里面的内容大概是下面表格中的样子。

位数

内容

取值

0

字头

0XCC

1

数据长度

低八位

2

数据长度

高八位

3

类型

0:心跳,1:登录

4

机器编码

0X00-0XFF

5

校验位

前面字节相加的低八位

这里把通讯协议简化了一下,仅剩下心跳和登录,如果有其他参数可以在此基础上进行扩展;从表格中可以看出来,每个字段数据位数还不一样,有的一位,有的两位,数据长度占两位,其他各占用一位。

只有这么一个文档,只有这么一丁点信息,其他就什么也不知道了,这可如何是好?不知道从哪里下手,这个疑问多多的项目就这样放了一段时间。

但是也不能总是这样放着呀,如果对接的人来了,我这边什么也没有,一下子也建不起一个项目呀?转念又想,曾经使用 **netty + google protobuf ** 开发过IM项目,也有些相似之处。这个DTU可否使用google protobuf呢?

于是,写了一个简单的客户端,一个服务端,来进行收发信息,google protobuf是通过对象编码成二进制进行数据通讯的,但文档中是字节数组,压根没有对象一说呀?写完了demo,测试一遍,但是和字节数组对应不起来,最后还是删掉了。

在网上找了很多资料,找来找去只找到这么两篇Java采用Netty实现基于DTU的TCP服务器 + 多端口 + 多协议

Java 使用Socket 实现基于DTU的TCP服务器 + 数据解析 + 心跳检测可以参考,试着把上面的demo扒拉了好几遍,通过这两篇文章,可以获得一些信息:

第一,可以使用netty和dtu进行通信,选择使用netty框架没有错;

第二,和dtu对接,接收到的是字节数组,不能使用google的protobuf框架,需要另做处理。

把参考文档中带netty的demo也试着在本地拷贝了一份,大概知道了对接收到的字节数组如何处理,但是demo中只有接收,没有发送,这是不够完美的;这也是个问题,单方面的,不好运行呀。

另外在处理字节数组的时候,在流程上还不是太标准,后面有可能会遇到半包、粘包的问题,这些都是需要面对的问题。结合自己曾经开发过IM的经验,把编解码处理和数据处理也分离出来,半包、粘包的问题一并考过进去,这样后面再完善就方便多了。

下面就开始SpringBoot2.1.4 + netty + DTU的客户端编码,难点就在于字节数组的解码和编码,一进一出,搞定了这一步,其他的业务逻辑就好处理了。这里的客户端编码是为了测试DTU的请求,以便和服务端互动起来,可以进行测试。

第一步,pom文件引入netty架包,就这两个架包足够用的了;

org.springframework.boot

spring-boot-starter

io.netty

netty-all

第二步,对字节数组的编解码,包括半包、粘包处理;

字节数据解码类ByteArrayDecoder:

import java.util.List;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.example.instant.ProtoInstant;

import com.example.util.CharacterConvert;

import io.netty.buffer.ByteBuf;

import io.netty.channel.ChannelHandlerContext;

import io.netty.handler.codec.ByteToMessageDecoder;

/**

* byte 1字节 (8位) -27~27-1 0 Byte 255

* short 2字节 (16位) -215~215-1 0 Short

* int 4字节 (32位) -231~ 231-1 0 Integer

* long 8字节 (64位) -263~263-1 0 Long

* char 2字节 (C语言中是1字节)可以存储一个汉字

* float 4字节 (32位) -3.4e+38 ~ 3.4e+38 0.0f Float

* double 8字节 (64位) -1.7e+308 ~ 1.7e+308 0 Double

* char 2字节(16位) u0000~uFFFF(‘’~‘?’) ‘0’ Character (0~216-1(65535))

* 布尔 boolean 1/8字节(1位) true, false FALSE Boolean

* C语言中,short、int、float、long、double,分别为:1个、2个、4个、8个、16个

* 对字节数组进行解码

* @author 程就人生

* @date 2020年8月3日

* @Description

*

*/

public class ByteArrayDecoder extends ByteToMessageDecoder{

private static Logger log = LoggerFactory.getLogger(ByteArrayDecoder.class);

@Override

protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {

// 标记一下当前的readIndex的位置

in.markReaderIndex();

//判断获取到的数据是否够字头,不沟通字头继续往下读

//字头:1位,数据串总长度:2位

if(in.readableBytes() < ProtoInstant.FILED_LEN){

log.info("不够包头,继续读!");

return;

}

//读取字头1位

int fieldHead = CharacterConvert.byteToInt(in.readByte());

if(fieldHead != ProtoI

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值