使用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;
}
public
DtuLoginMessage(DtuType type, String
regCode){
this.dtuType = type;
this.regCode = regCode;
}
}
二、解决方案
既然无法无法使用工具类来解决粘包、拆包的问题,那就需要自己去解析每个字节,那就要自定义一个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 =
DtuLoginHandlerContainer.getInstance().decode(in);
if (loginMsg != null)
out.add(loginMsg);
}
每次decode被调用,都去检查一下是否是某个dtu的注册包,如果是,就添加到out中;如果不是,那就什么都不用管,这样下次decode被调用的时候还会包含之前所有没有被解析的字节内容。
使用Netty绑定一个端口如何分辨出多种类型的DTU的注册包的更多相关文章
- 一个电器工厂可以生产多种类型的电器,如海尔工厂可以生产海尔电视机、海尔空调等,TCL工厂可以生产TCL电视机,TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构,现使用
一个电器工厂可以生产多种类型的电器,如海尔工厂可以生产海尔电视机.海尔空调等,TCL工厂可以生产TCL电视机,TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构,现使用 ...
- 一个服务器的IIS只能绑定一个HTTPS也就是443端口
默认情况一个服务器的IIS只能绑定一个HTTPS也就是443端口 要实现多个站点对应HTTPS只能更改IIS配置 地址:C:\Windows\System32\inetsrv\config\appli ...
- Netty服务端Channel注册Selector及绑定服务器端口
当服务端Channel 创建并且初始化完成之后,会将其注册到 selector,通过语句config().group().register(channel)进行注册工作,该方法最终调用 Abstrac ...
- 如何用Netty实现一个轻量级的HTTP代理服务器
为什么会想通过Netty构建一个HTTP代理服务器?这也是笔者发表这篇文章的目的所在. 其主要还是源于解决在日常开发测试过程中,一直困扰测试同学很久的一个问题,现在我就来具体阐述一下这个问题. 在日常 ...
- Netty实现一个简单聊天系统(点对点及服务端推送)
Netty是一个基于NIO,异步的,事件驱动的网络通信框架.由于使用Java提供 的NIO包中的API开发网络服务器代码量大,复杂,难保证稳定性.netty这类的网络框架应运而生.通过使用netty框 ...
- 手写一个类SpringBoot的HTTP框架:几十行代码基于Netty搭建一个 HTTP Server
本文已经收录进 : https://github.com/Snailclimb/netty-practical-tutorial (Netty 从入门到实战:手写 HTTP Server+RPC 框架 ...
- netty系列之:来,手把手教你使用netty搭建一个DNS tcp服务器
目录 简介 搭建netty服务器 DNS服务器的消息处理 DNS客户端消息请求 总结 简介 在前面的文章中,我们提到了使用netty构建tcp和udp的客户端向已经公布的DNS服务器进行域名请求服务. ...
- IIS服务器多域名证书绑定443端口解决方案
一个服务器IIS要绑定多个HTTPS站点(该方法在此之前,有进行测试其他网站域名的ssl证书,测试没有问题) 默认情况一个服务器的IIS只能绑定一个HTTPS也就是443端口 要实现多个站点对应HTT ...
- node如何让一个端口同时支持https与http
众所周知node是一个高性能的web服务器,使用它可以很简单的创建一个http或https的服务器. 比如一个很简单的http服务器: var http = require('http'); var ...
随机推荐
- Learning The Bash Shell读书笔记(整理)
最近搞了一本书 Learning Bash Shell,发现有人已经写了阅读笔记,我就在这边整理一下 来自blog:http://blog.sina.com.cn/n4mine Learning Th ...
- javascript多态 - 类形式实现demo
/* *多态 * 对传入的参数做判断以实现多种调用方式 */ //类形式实现 function Add(){ function zero(){ return 10; } function one(nu ...
- SqlServer服务器和数据库角色
首先我们来阐述服务器(实例级别)的权限,实例级别和数据库级别权限的最大不同在于:实例级别的权限是直接授权给登录名,而数据库级别的全显示授予数据库用户的,然后数据库用户再与登录名匹配.(再SqlServ ...
- MongoDB学习笔记——Master/Slave主从复制
Master/Slave主从复制 主从复制MongoDB中比较常用的一种方式,如果要实现主从复制至少应该有两个MongoDB实例,一个作为主节点负责客户端请求,另一个作为从节点负责从主节点映射数据,提 ...
- C#读取XML文件
--硬盘Xml文件存储路径:d:\xmlFile\Testxml.xml xml文件内容: <Root> <Tab> <ID>245575913</ID> ...
- Mysql 如何实现列值的合并
Mysql 如何实现列值的合并 SELECT GROUP_CONCAT(name SEPARATOR ' ') AS name FROM A
- System V IPC(1)-消息队列
一.概述 System V三种IPC:消息队列,信号量,共享内存.这三种IPC最先出现在AT&am ...
- ARM学习篇一 点亮LED
要点亮LED,先决条件是什么,当然得有相应的硬件设施.板子的整个电路图比较大,我就直接取相关部分. 给发光二级管加上3.3v电压后,通过1k电阻,直接与S3C2440连接.至于为什么要加电阻,大家应该 ...
- Objective-C基础数据类型-NSSet[转]
转自GISerYang 集合: 集合(NSSet)和数组(NSArray)有相似之处,都是存储不同的对象的地址:不过NSArray是有序的集合,NSSet是无序的集合. 集合是一种哈希表,运用散列算法 ...
- UVA 12716 GCD XOR【异或】
参考:http://www.cnblogs.com/naturepengchen/articles/3952145.html #include<stdio.h> #include<s ...