netty之LengthFieldBasedFrameDecoder解码器
官方api:http://netty.io/4.1/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html
package com.eshore.ismp.hbinterface.sps; import java.nio.charset.Charset; import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.eshore.ismp.hbinterface.service.BizCommonService; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; public class SpsServer4 {
private static final Logger logger = Logger.getLogger(SpsServer4.class);
private static int PORT = 10002;
/**用于分配处理业务线程的线程组个数 */
protected static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2; //默认
/** 业务出现线程大小*/
protected static final int BIZTHREADSIZE = 4;
/*
* NioEventLoopGroup实际上就是个线程池,
* NioEventLoopGroup在后台启动了n个NioEventLoop来处理Channel事件,
* 每一个NioEventLoop负责处理m个Channel,
* NioEventLoopGroup从NioEventLoop数组里挨个取出NioEventLoop来处理Channel
*/
private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);
private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE); protected static void run(final BizCommonService bizCommonService) throws Exception {
//String PORTs=ConfigLoadUtil.getValue("toSpsServerPort");
//PORT=Integer.parseInt(PORTs);
//logger.info("PORT IS:"+PORT);
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);
b.channel(NioServerSocketChannel.class);
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
/* pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8)); */
pipeline.addLast(new MessageDecoder(Integer.MAX_VALUE,18,4,-22,0));
pipeline.addLast("decoder", new StringDecoder(Charset.forName("GBK")));
pipeline.addLast("encoder", new StringEncoder(Charset.forName("GBK")));
pipeline.addLast(new SpsServerHandler(bizCommonService));
}
}); b.bind(PORT).sync();
logger.info("TCP服务器已启动");
} protected static void shutdown() {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
} public static void main(String[] args) throws Exception {
try{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "applicationContext.xml" });
context.start();
BizCommonService bizCommonService = (BizCommonService) context.getBean("bizCommonService");
SpsServer4.run(bizCommonService);
}catch(Exception e){
logger.error("start sps interface server error:",e);
System.exit(-1);
}
}
}
MessageDecoder:
package com.eshore.ismp.hbinterface.sps; import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder; public class MessageDecoder extends LengthFieldBasedFrameDecoder{
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public MessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment,
int initialBytesToStrip) {
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
} @Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception{
return super.decode(ctx, in);
}
@Override
protected long getUnadjustedFrameLength(ByteBuf buf, int offset, int length, ByteOrder order){
long frameLength;
switch (length) {
case 1:
frameLength = buf.getUnsignedByte(offset);
break;
case 2:
frameLength = buf.getUnsignedShort(offset);
break;
case 3:
frameLength = buf.getUnsignedMedium(offset);
break;
case 4:
//frameLength = buf.getUnsignedInt(offset);
frameLength=buf.readableBytes();
logger.info("==="+frameLength);
byte[] cc=new byte[buf.readableBytes()];
ByteBuf tmp=buf.copy();
tmp.readBytes(cc);
try {
String ss=new String(cc,"GBK");
frameLength=Integer.parseInt(ss.substring(offset,offset+length));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
break;
case 8:
frameLength = buf.getLong(offset);
break;
default:
throw new DecoderException(
"unsupported lengthFieldLength: "
+ length + " (expected: 1, 2, 3, 4, or 8)");
}
return frameLength;
} }
其中,报文长度为6位:17-22
参考 https://blog.csdn.net/bestone0213/article/details/47108419
参考:https://www.jianshu.com/p/a0a51fd79f62
参考:https://blog.csdn.net/zougen/article/details/79037675
netty之LengthFieldBasedFrameDecoder解码器的更多相关文章
- Netty 中 LengthFieldBasedFrameDecoder 构造函数取值备忘
public LengthFieldBasedFrameDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, ...
- Netty学习(六)-LengthFieldBasedFrameDecoder解码器
在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...
- netty中LengthFieldBasedFrameDecoder的使用
在org.jboss.netty.handler.codec.frame包中,有LengthFieldBasedFrameDecoder类用来解析带有长度属性的包,只要我们在传输协议中加入包的总长度就 ...
- 【Netty】使用解码器Decoder解决TCP粘包和拆包问题
解码器Decoder和ChannelHandler的关系 netty的解码器通常是继承自ByteToMessageDecoder,而它又是继承自ChannelInboundHandlerAdapter ...
- 基于Netty的私有协议栈的开发
基于Netty的私有协议栈的开发 书是人类进步的阶梯,每读一本书都使自己得以提升,以前看书都是看了就看了,当时感觉受益匪浅,时间一长就又还回到书本了!所以说,好记性不如烂笔头,以后每次看完一本书都写一 ...
- netty通用解码器LengthFieldBasedFrameDecoder
2.2.4. LengthFieldBasedFrameDecoder解码器 了解TCP通信机制的读者应该都知道TCP底层的粘包和拆包,当我们在接收消息的时候,显示不能认为读取到的报文就是个整包消息, ...
- Netty源码分析 (十一)----- 拆包器之LengthFieldBasedFrameDecoder
本篇文章主要是介绍使用LengthFieldBasedFrameDecoder解码器自定义协议.通常,协议的格式如下: LengthFieldBasedFrameDecoder是netty解决拆包粘包 ...
- Netty 解码器抽象父类 ByteToMessageDecoder 源码解析
前言 Netty 的解码器有很多种,比如基于长度的,基于分割符的,私有协议的.但是,总体的思路都是一致的. 拆包思路:当数据满足了 解码条件时,将其拆开.放到数组.然后发送到业务 handler 处理 ...
- Netty源码分析第6章(解码器)---->第1节: ByteToMessageDecoder
Netty源码分析第六章: 解码器 概述: 在我们上一个章节遗留过一个问题, 就是如果Server在读取客户端的数据的时候, 如果一次读取不完整, 就触发channelRead事件, 那么Netty是 ...
随机推荐
- DBA不可不知的操作系统内核参数
背景 操作系统为了适应更多的硬件环境,许多初始的设置值,宽容度都很高. 如果不经调整,这些值可能无法适应HPC,或者硬件稍好些的环境. 无法发挥更好的硬件性能,甚至可能影响某些应用软件的使用,特别是数 ...
- ROS 教程之 network:多台计算机之间网络通信(2)
在上一篇文章中我们已经搭建好了两台计算机间通信的条件,但是每次都需要在新的终端里输入一长串export ROS_MASTER_URI之类的.实际弄起来的时候也不方便,因此在本文中,我们更进一步,简化两 ...
- Spring Boot集成Mybatis及通用Mapper
集成Mybatis可以通过 mybatis-spring-boot-starter 实现. <!-- https://mvnrepository.com/artifact/org.mybatis ...
- C#中的程序集和命名空间
C#中的程序集和命名空间 如果说命名空间是类库的逻辑组织形式,那么程序集就是类库的物理组织形式.只有同时指定类型所在的命名空间及实现该类型的程序集,才能完全限定该类型.<精通.NET核心技术-- ...
- 防止 apk反编译 jocky-- java混淆代码 (转至:http://my.oschina.net/f839903061/blog/72554)
1.下载jocky,解压后把整个文件夹复制到Eclipse的plugin目录.2.重启Eclipse,在项目上点右键,如果出现jocky菜单,则安装成功. 3.在项目上点右键,选菜单jocky-> ...
- Oracle之唯一性约束(UNIQUE Constraint)使用方法具体解释
Oracle | PL/SQL唯一索引(Unique Constraint)使用方法 1 目标 用演示样例演示怎样创建.删除.禁用和使用唯一性约束. 2 什么是唯一性约束? 唯一性约束指表中一个字段或 ...
- SharePoint Server 2013 通过IP无法访问站点
通过IP访问SharePoint站点,出现“The Web application at http://172.21.19.132:1000 could not be found.... ”如下错误: ...
- 基于.Net实现前端对话框和消息框
关于前端对话框.消息框的优秀插件多不胜数.造轮子是为了更好的使用轮子,并不是说自己造的轮子肯定好.所以,这个博客系统基本上都是自己实现的,包括日志记录.响应式布局等等一些本可以使用插件的.好了,废话不 ...
- ubuntu-15.04-desktop-amd64.iso:ubuntu-15.04-desktop-amd64:安装Oracle11gR2
ubuntu 桌面版的安装不介绍. 如何安装oracle:核心步骤和关键点. ln -sf /bin/bash /bin/sh ln -sf /usr/bin/basename /bin/basena ...
- ChemDraw常用到的几种技巧
ChemDraw对于化学学习的重要性相当于CAD和建筑学.PS和设计,所以如果你是一名生化相关的工作人员,拥有ChemDraw并掌握ChemDraw的使用方法十分必要!这是一款对于我们研究化学的人来说 ...