Mina的IoBuffer改造成Netty的ByteBuff
背景:部标GPS通讯底层全部改造成基于Netty服务器实现的,现将Mina的依赖移除,修改过程中有用到缓冲区的读写。现做了如下修改:
原有基于Mina的IoBuffer对字节读写封装代码如下:
package com.hns.gps.gw.jt808.protocol; import com.hns.gps.gw.jt808.utils.Tools;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer; import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset; public class MyBuffer {
private Logger logger = Logger.getLogger(MyBuffer.class);
IoBuffer buff; public MyBuffer() {
buff.setUseDirectBuffer(false);
buff = IoBuffer.allocate(1536);
buff.mark();
} public MyBuffer(int len) {
buff.setUseDirectBuffer(false);
buff = IoBuffer.allocate(len);
buff.mark();
} public MyBuffer(byte[] bytes) {
if (bytes.length > 1024)
buff = IoBuffer.allocate(bytes.length + 100);
else
buff = IoBuffer.allocate(1024);
buff.mark();
buff.put(bytes);
buff.limit(bytes.length);
buff.reset();
}
public MyBuffer(byte[] bytes, int start, int length) {
buff = IoBuffer.allocate(length);
buff.mark();
buff.put(bytes, start, length);
buff.limit(length);
buff.reset();
} public void clear() {
buff.clear();
buff.mark();
} public void put(byte a) {
buff.put(a);
} public void put(long a)
{
buff.putLong(a);
} public void put(short a) {
buff.putShort(a);
} public void put(byte[] a) {
buff.put(a);
} public boolean hasRemain() {
return buff.remaining() > 0;
} public void put(int a) {
buff.putInt(a);
} public void putShort(int a) {
buff.putShort((short) a);
} public void put(String str) {
// US-ASCII try {
byte[] b = str.getBytes("gbk");
buff.put(b); } catch (Exception e) {
// logger.error(e.getMessage(), e);
}
} public void putBcd(String str, int length)
{
byte[] b = BcDToBytes(str,length);
buff.put(b);
} public static String BytesToBcd(byte[] bytes, int start, int len) {
StringBuilder bcd = new StringBuilder();
for (int m = 0; m < len; m++) {
bcd.append(String.format("%02X", bytes[start + m]));
}
return bcd.toString();
} public static byte[] BcDToBytes(String bcd, int len) {
bcd = bcd == null ? "" : bcd;
while (bcd.length() < len) {
bcd = "0" + bcd;
}
return Tools.HexString2Bytes(bcd);
} public void put(String str, int len) {
byte[] result = new byte[len];
try {
byte[] b = str.getBytes("gbk"); System.arraycopy(b, 0, result, 0, b.length); for (int m = b.length; m < len; m++) {
result[m] = 0;
}
buff.put(result); } catch (Exception e) {
//logger.error(e.getMessage(), e);
}
} public byte get() {
return buff.get();
} public byte[] gets(int len) {
byte[] data = new byte[len];
buff.get(data);
return data;
} public int getInt() {
return buff.getInt();
} public short getShort() {
return buff.getShort();
} public long getLong() {
return buff.getLong();
} // 将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。
public int getUnsignedShort() {
short t = buff.getShort();
return t & 0xffff;
} // 将data字节型数据转换为0~255 (0xFF 即BYTE)。
public int getUnsignedByte() {
return buff.get() & 0x0FF;
} public long getUnsignedInt() {
return buff.getInt() & 0x0FFFFFFFF;
} public String getString() {
try {
String strTemp = buff
.getString(Charset.forName("GBK").newDecoder());
return strTemp;
} catch (CharacterCodingException e) {
e.printStackTrace();
}
return "";
} public String getString(int len) {
try {
String strTemp = buff.getString(len, Charset.forName("GBK")
.newDecoder());
return strTemp;
} catch (CharacterCodingException e) {
e.printStackTrace();
gets(len);
}
return "";
} public String getBcdString(int len) {
byte[] bytes = this.gets(len);
StringBuilder bcd = new StringBuilder();
for (int m = 0; m < len; m++) {
bcd.append(String.format("%02X", bytes[m]));
}
return bcd.toString();
} public byte[] array() {
int pos = buff.position();
byte[] data = new byte[pos];
buff.reset();
buff.get(data);
return data;
} public static void main(String[] args) { IoBuffer ib = IoBuffer.allocate(1024);
ib.mark();
ib.put((byte) 128);
ib.reset();
// byte b = ib.get();
// int x = b& 0xff;
short x = ib.getUnsigned(); short y = ib.getUnsigned(0); System.out.println("" + x + "," + y);
} }
后修改成Netty版的ByteBuffer操作实现如下:
package com.hns.gps.gw.jt808.protocol; import com.hns.gps.gw.jt808.utils.Tools;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.ResourceLeakDetector;
import org.apache.log4j.Logger; import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset; /**
* ByteBuffer缓冲区,用Netty实现
*
* @author linys
* @create 2018-06-12
* @since 1.0.0
*/
public class ByteBuffer {
private Logger logger = Logger.getLogger(ByteBuffer.class);
protected ByteBuf buff; public ByteBuffer() {
buff = ByteBufAllocator.DEFAULT.ioBuffer(1536);
//为了找到ByteBuff没有被释放的原因 (上线关闭)
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
} public ByteBuffer(byte[] bytes) {
buff = ByteBufAllocator.DEFAULT.ioBuffer(bytes.length);
buff.writeBytes(bytes);
//为了找到ByteBuff没有被释放的原因 (上线关闭)
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
} public ByteBuffer(byte[] bytes, int start, int length) {
buff = ByteBufAllocator.DEFAULT.ioBuffer(length);
buff.writeBytes(bytes, start, length);
//为了找到ByteBuff没有被释放的原因 (上线关闭)
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
} public void clear() {
buff.clear();
buff.markWriterIndex();
buff.markReaderIndex();
} public void put(byte a) {
buff.writeByte(a);
} public void put(long a) {
buff.writeLong(a);
} public void put(short a) {
buff.writeShort(a);
} public void put(byte[] a) {
buff.writeBytes(a);
} public boolean hasRemain() {
return buff.isReadable();
} public void put(int a) {
buff.writeInt(a);
} public void put(String str) {
// US-ASCII
try {
byte[] b = str.getBytes("gbk");
buff.writeBytes(b);
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
}
} public String getBcdString(int len) {
byte[] bytes = this.gets(len);
StringBuilder bcd = new StringBuilder();
for (int m = 0; m < len; m++) {
bcd.append(String.format("%02X", bytes[m]));
}
return bcd.toString();
} public void putBcd(String str, int length) {
byte[] b = BcDToBytes(str, length);
buff.writeBytes(b);
} public static byte[] BcDToBytes(String bcd, int len) {
bcd = bcd == null ? "" : bcd;
while (bcd.length() < len) {
bcd = "0" + bcd;
}
return Tools.HexString2Bytes(bcd);
} public static String BytesToBcd(byte[] bytes, int start, int len) {
StringBuilder bcd = new StringBuilder();
for (int m = 0; m < len; m++) {
bcd.append(String.format("%02X", bytes[start + m]));
}
return bcd.toString();
} public void put(String str, int len) {
byte[] result = new byte[len];
try {
byte[] b = str.getBytes("gbk");
System.arraycopy(b,0, result,0, b.length);
for (int m = b.length; m < len; m++) {
result[m] = 0; //不够位补0
}
buff.writeBytes(result);
} catch (UnsupportedEncodingException e) {
logger.error(e.getMessage(), e);
}
} public byte get() {
return buff.readByte();
} public short getShort() {
return buff.readShort();
} public int getInt() {
return buff.readInt();
} public long getLong() {
return buff.readLong();
} public double getDouble() {
return buff.readDouble();
} public byte[] gets(int len) {
byte[] data = new byte[len];
buff.readBytes(data);
return data;
} // 将data字节型数据转换为0~255 (0xFF 即BYTE)。
public short getUnsignedByte() {
return buff.readUnsignedByte();
} // 将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。
public int getUnsignedShort() {
return buff.readUnsignedShort();
} public long getUnsignedInt() {
return buff.readUnsignedInt();
} public String getString() {
return buff.toString(Charset.forName("GBK"));
} public String getString(int len) {
return buff.toString(0, len, Charset.forName("GBK"));
} /**
* 转换成byte数组
* @return
*/
public byte[] toByteArray() {
int pos = buff.writerIndex();
byte[] data = new byte[pos];
buff.readBytes(data);
//再次调用重新从头读
buff.resetReaderIndex();
return data;
} /**
* 清空释放buff,在buff使用结束后调用
* @return
*/
public void release() {
this.clear();
//释放缓冲区内存
ReferenceCountUtil.release(buff);
} /**
* 转换成byte数组并清空释放buff,在buff使用结束后调用
* @return
*/
public byte[] toByteArrayAndRelease() {
int pos = buff.writerIndex();
byte[] data = new byte[pos];
buff.readBytes(data);
this.clear();
//释放缓冲区内存
ReferenceCountUtil.release(buff);
return data;
} }
总结:处理网络数据的项目中经常需要处理字节数据,Java的ByteBuffer很强大,对于NIO的ByteBuffer字节读写缓冲区操作,Mina和Netty都有封装,IoBuffer基于Java原生ByteBuffer封装而成,ByteBuff则是Netty自己独有的字节数据Buffer,Netty提供了更强大的封装并能实现零拷贝,更加方便我们操作字节缓冲区,推荐使用netty的ByteBuff!代码供大家对ByteBuff的封装参考。
文章封装的代码基于连接:
https://blog.csdn.net/alex_bean/article/details/51251015
https://blog.csdn.net/u010853261/article/details/53690780
https://www.cnblogs.com/zzt-lovelinlin/p/5292608.html
Mina的IoBuffer改造成Netty的ByteBuff的更多相关文章
- MINA系列学习-IoBuffer
在阅读IoBuffer源码之前,我们先看Mina对IoBuffer的描述:A byte buffer used by MINA applications. This is a replacement ...
- Mina、Netty、Twisted一起学(四):定制自己的协议
在前面的博文中,介绍一些消息分割的方案,以及MINA.Netty.Twisted针对这些方案提供的相关API.例如MINA的TextLineCodecFactory.PrefixedStringCod ...
- 【MINA】缓存区ByteBuffer和IOBuffer你要了解的常用知识
mina中IOBuffer是Nio中ByteBuffer的衍生类,主要是解决Bytebuffer的两个不足 1.没有提供足够灵活的get/putXXX方法 2.它容量固定,难以写入可变长度的数据 特点 ...
- 【读后感】Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ?
[读后感]Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ? 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...
- Mina、Netty、Twisted一起学(六):session
开发过Web应用的同学应该都会使用session.由于HTTP协议本身是无状态的,所以一个客户端多次访问这个web应用的多个页面,服务器无法判断多次访问的客户端是否是同一个客户端.有了session就 ...
- Java NIO框架Mina、Netty、Grizzly介绍与对比(zz)
Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...
- Java NIO框架Mina、Netty、Grizzly介绍与对比
Mina:Mina(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用 ...
- Mina源码阅读笔记(二)- IoBuffer的封装
在阅读IoBuffer源码之前,我们先看Mina对IoBuffer的描述:A byte buffer used by MINA applications. This is a replacement ...
- Java NIO框架 Mina、Netty、Grizzly
Mina Mina(Multipurpose Infrastructure for Network Applications) 是 Apache组织一个较新的项目,它为开发高性能和高可用性的网络应用程 ...
随机推荐
- nvidia-docker+cuda8.0+ubuntu16.04
nvidia-docker安装 如果之前安装过docker1.0版本,需要先删掉该版本和之前创建的容器 docker volume ls -q -f driver=nvidia-docker | xa ...
- [Abp 源码分析]十二、多租户体系与权限验证
0.简介 承接上篇文章我们会在这篇文章详细解说一下 Abp 是如何结合 IPermissionChecker 与 IFeatureChecker 来实现一个完整的多租户系统的权限校验的. 1.多租户的 ...
- Python内置函数(35)——issubclass
英文文档: issubclass(class, classinfo) Return true if class is a subclass (direct, indirect or virtual) ...
- 8.Django缓存和信号
缓存 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将某个views的返回值保存至内存或者memcache中, ...
- InstallShield Limited Edition Project 打包windows服务解析
最近项目从vs2005 升级到vs2010后,发现新的vs2010 不再带有原来的安装工程项目,导致以前的安装包不可以使用,查找资料后发现微软从vs2010 版本后不再提供自带的安装工程,尝试着利用 ...
- springboot+mybatis+dubbo+aop日志第一篇
本篇文章主要讲述项目搭建过程,不会涉及过多的基础知识,本项目是作者对前段时间学习的一个总结,主要使用到技术有:maven父子工程.springboot.mybatis.dubbo.zookeeper. ...
- leetcode — path-sum
/** * Source : https://oj.leetcode.com/problems/path-sum/ * * * Given a binary tree and a sum, deter ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(1)- 源文件(.c/.h/.s)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的source文件. 众所周知,嵌入式开发属于偏底层的开发,主要编程语言是C和汇编.所以本文要讲的source文件主要指的就是 ...
- 痞子衡嵌入式:串口调试工具Jays-PyCOM诞生记(5)- 软件优化
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是串口调试工具Jays-PyCOM诞生之软件优化. 前面痞子衡已经初步实现了Jays-PyCOM的串口功能,并且通过了最基本的测试,但目前 ...
- c# ?? 和?
static void Main(string[] args) { double? num1 = null; // ? 说明num1可以为空 ...