netty之LengthFieldBasedFrameDecoder解码器
官方api:http://netty.io/4.1/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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
作者: lost blog
出处: http://www.cnblogs.com/JAYIT/
关于作者:专注服务器端开发
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接 如有问题, 可邮件(sawyershaw@qq.com)咨询.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步