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

参考:https://www.jianshu.com/p/a0a51fd79f62

参考:https://blog.csdn.net/zougen/article/details/79037675

posted @   Lost blog  阅读(977)  评论(0编辑  收藏  举报




点击右上角即可分享
微信分享提示