官方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解码器的更多相关文章

  1. Netty 中 LengthFieldBasedFrameDecoder 构造函数取值备忘

    public LengthFieldBasedFrameDecoder(ByteOrder byteOrder, int maxFrameLength, int lengthFieldOffset, ...

  2. Netty学习(六)-LengthFieldBasedFrameDecoder解码器

    在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...

  3. netty中LengthFieldBasedFrameDecoder的使用

    在org.jboss.netty.handler.codec.frame包中,有LengthFieldBasedFrameDecoder类用来解析带有长度属性的包,只要我们在传输协议中加入包的总长度就 ...

  4. 【Netty】使用解码器Decoder解决TCP粘包和拆包问题

    解码器Decoder和ChannelHandler的关系 netty的解码器通常是继承自ByteToMessageDecoder,而它又是继承自ChannelInboundHandlerAdapter ...

  5. 基于Netty的私有协议栈的开发

    基于Netty的私有协议栈的开发 书是人类进步的阶梯,每读一本书都使自己得以提升,以前看书都是看了就看了,当时感觉受益匪浅,时间一长就又还回到书本了!所以说,好记性不如烂笔头,以后每次看完一本书都写一 ...

  6. netty通用解码器LengthFieldBasedFrameDecoder

    2.2.4. LengthFieldBasedFrameDecoder解码器 了解TCP通信机制的读者应该都知道TCP底层的粘包和拆包,当我们在接收消息的时候,显示不能认为读取到的报文就是个整包消息, ...

  7. Netty源码分析 (十一)----- 拆包器之LengthFieldBasedFrameDecoder

    本篇文章主要是介绍使用LengthFieldBasedFrameDecoder解码器自定义协议.通常,协议的格式如下: LengthFieldBasedFrameDecoder是netty解决拆包粘包 ...

  8. Netty 解码器抽象父类 ByteToMessageDecoder 源码解析

    前言 Netty 的解码器有很多种,比如基于长度的,基于分割符的,私有协议的.但是,总体的思路都是一致的. 拆包思路:当数据满足了 解码条件时,将其拆开.放到数组.然后发送到业务 handler 处理 ...

  9. Netty源码分析第6章(解码器)---->第1节: ByteToMessageDecoder

    Netty源码分析第六章: 解码器 概述: 在我们上一个章节遗留过一个问题, 就是如果Server在读取客户端的数据的时候, 如果一次读取不完整, 就触发channelRead事件, 那么Netty是 ...

随机推荐

  1. node-webkit连接mysql

    一.安装node.js mysql驱动库 node-webkit里面没有mysql模块的,我们需要安装mysql模块.我们可以使用npm(Node package manager)进行安装.这里使用到 ...

  2. 【转】记一次ASP.NET MVC性能优化(实际项目中)

    前言 在开发中为了紧赶项目进度而未去关注性能的问题,在项目逐渐稳定下来后发现性能令人感到有点忧伤,于是开始去关注这方面,本篇为记录在开发中遇到的问题并解决,不喜勿喷.注意:以下问题都是在移动端上出现, ...

  3. Windows 上 GitHub Desktop 的操作[转]

    第1章 上传开源代码至GitHub    1 1.1 git Windows 客户端    1 1.2 注册GitHub账户    2 1.3 登录    2 1.4 创建本地代码仓库    2 1. ...

  4. 图片后门捆绑利用工具 – FakeImageExploiter

    在这里,要向大家推荐一款名为“Fake Image Exploiter”的安全工具,该工具可以在图片文件中捆绑隐藏的恶意.bat或.exe程序,方便钓鱼或社工攻击测试过程中的入侵控制.如果受害者点击该 ...

  5. php中ignore_user_abort函数的用法(定时)

    PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行,可以用它来实现计划任务与持续进程,下面会通过实例讨论ignore_user_abort()函数的作用与用法. i ...

  6. u3d change terrain textrue&height

    using UnityEngine; using System.Collections; public class terrainTest : MonoBehaviour { ; private Te ...

  7. 第五章 使用 SqlSession(MyBatis)

    在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession.一旦你获得一个 session 之后,你可以使用它来执行映射语句,提交或回滚连接,最后,当不再需要 ...

  8. Java 9的日期时间格式化趋近Unicode区域设置标准

        1.JDK-8148947,DataTimeFormatter的模式字母“g”:正如在LDML中定义的,字母“g”指代一个“简化儒略日期”,简化儒略日期与正常儒略日期的差别在于:(1)简化儒略 ...

  9. ios开发之--ZHPickView输出格式不出现 +0000

    这样写就不会输出 +0000了 NSDate *select = [_datePicker date]; NSDateFormatter *dateFormatter = [[NSDateFormat ...

  10. ios开发之 -- 自动轮播图创建

    这里是oc版本的,简单记录下: 具体代码如下: 1,准备 #define FRAME [[UIScreen mainScreen] bounds] #define WIDTH FRAME.size.w ...