使⽤Netty绑定⼀个端⼝如何分辨出多种类型的DTU的注册包⼀、背景
项⽬需要使⽤Netty和DTU(⽆线数据传输模块)通信,需要接⼊多种类型的DTU,每种dtu连接上来之后都⾸先会发送⼀个注册报⽂。需要解析该注册报⽂来实现:
1. 分辨出是哪种类型的dtu;
2. 从注册报⽂中识别出注册码,以便决定该dtu下⾯连接的是哪个装置。
问题在于这是两个不同⼚家的DTU,他们的注册报⽂的内容和长度都不相同。此时我们就⽆法使⽤诸
如DelimitedBasedFrameDecoder、FixedLengthFrameDecoder这样现成的⼯具类来解决粘包的问题,需要⾃⼰去解析收到的每个字节,然后分别是判断对应的报⽂是哪种DTU的注册报⽂,把不同种类的注册包解析成内部消息。
public class DtuLoginMessage {
public enum DtuType{
dtJingfuyuan,
dtTopIot
}
private DtuType dtuType;
private String regCode;
public DtuType getDtuType() {
return dtuType;
}
public String getRegCode() {
return regCode;
}enum类型如何使用
public DtuLoginMessage(DtuType type, String regCode){
this.dtuType = type;
}
}
⼆、解决⽅案
解决⽅案
⼆、
既然⽆法⽆法使⽤⼯具类来解决粘包、拆包的问题,那就需要⾃⼰去解析每个字节,那就要⾃定义⼀个ChannelHandler⼦类来讲随机收到的ByteBuf转换为DtuLoginMessage,我们⼀般写ChannelHandler都是直接继承⾃ChannelInboundHandlerAdapter,然后去override他的channelRead⽅法,如果直接⽤这个类也不是不⾏,但是那就意味着⾃⼰要定义⼀个缓冲区来接受每次channelRead传递过来的字节,每次有新的字节过来,就要先写⼊到缓冲区,然后再去检查⼀下当前缓冲区的这些数据是否已经是某个dtu的注册包了,如果是的话就可以往后⾛了。这⾥存在的主要问题是要⾃⼰去维护这个缓冲区,如果有什么⼯具类可以帮我们维护就更好了,记得曾经在哪⾥看过。
没错,ByteToMessageDecoder就是⼲这活的,可以让⾃⼰的Handler继承ByteToMessageDecoder,然后重写其中的decode⽅法,该⽅法的签名如下,实例代码如下:
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
DtuLoginMessage loginMsg = Instance().decode(in);
if (loginMsg != null)
out.add(loginMsg);
}
每次decode被调⽤,都去检查⼀下是否是某个dtu的注册包,如果是,就添加到out中;如果不是,那就什么都不⽤管,这样下次decode被调⽤的时候还会包含之前所有没有被解析的字节内容。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论