• 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

  • 相关阅读:
    TestNg线程池配置、执行次数配置、超时配置
    testng.xml文件结构组成及节点属性说明
    ReportNg 测试报告的定制修改【转】
    TestNg依赖详解(三)------灵活的文件配置依赖
    TestNg依赖高级用法之强制依赖与顺序依赖------TestNg依赖详解(二)
    TestNg依赖配置基础用法(单一方法依赖)------TestNg依赖详解(一)
    compareTo,Comparator和equals
    HashMap源码解析
    redis的相关知识
    IO模型
  • 原文地址:https://www.cnblogs.com/JAYIT/p/8855814.html
Copyright © 2020-2023  润新知