LengthFieldBasedFrameDecoder详解

public LengthFieldBasedFrameDecoder(
            int maxFrameLength, int lengthFieldOffset, int lengthFieldLength,
            int lengthAdjustment, int initialBytesToStrip, boolean failFast)

这是源码里的六个参数:
//1.单个包最大长度
//2.长度字段开始位置偏移量
//3.长度字段所占字节数
//4.长度字段默认表示后续报文的长度
//5.从解码帧中剥离的第一个字节数(0表示解码过程中不丢弃任何数据)
//6.默认为true,表示读取到长度域的值超过Integer.MAX_VALUE时抛异常,false表示真正读取完才抛异常,建议不要修改,否则可能会造成内存溢出

协议接口要求:
在这里插入图片描述

直接上图我写的:

/**
 * 服务端
 */
public class ServerP {
    public void bind(int port) throws InterruptedException {
        //创建用于接受客户端的线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //创建用于处理网络操作的线程组
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //创建服务端启动助手用于配置参数
            ServerBootstrap b = new ServerBootstrap();
            //设置2个线程组
            b.group(bossGroup,workerGroup)
                    //设置通道的底层实现
                    .channel(NioServerSocketChannel.class)
                    //option是NioServerSocketChannel提供的用来接收进来的连接
                    .option(ChannelOption.SO_BACKLOG,1024)
                    //childOption是NioServerSocketChannel接收到的连接
                    .childOption(ChannelOption.SO_KEEPALIVE,true)
                    //childHandler为建立连接之后的执行器
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel sc) throws Exception {
                            //*注意自定义长度处理器要写在首位*
                            //1.单个包最大长度
                            //2.长度字段开始位置偏移量
                            //3.长度字段所占字节数
                            //4.长度字段默认表示后续报文的长度
                            //5.解码过程中不丢弃任何数据
                            //6.默认为true,表示读取到长度域的值超过Integer.MAX_VALUE时抛异常,false表示真正读取完才抛异常,建议不要修改,否则可能会造成内存溢出
                            sc.pipeline().addLast("frameDecoder",new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,2,2,2,0,true));
                            //对接收到的客户端进行解码
                            sc.pipeline().addLast("decoder",new MsgDeCode());
                            //编码
                            sc.pipeline().addLast("encode",new MsgEnCode());
                            sc.pipeline().addLast("handler",new SHandler());
                        }
                    });
            //绑定端口,同步等待
            ChannelFuture cf = b.bind(port).sync();
            //监听服务器端口关闭
            cf.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //优雅推出,释放线程池资源
            System.out.println("服务器关闭...");
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        int port = 9527;
        System.out.println("服务端已经启动...");
        new ServerP().bind(port);
    }

根据协议接口的要求这样设置好参数后,客户端发送的单条消息字节数如果正好是28,合并的消息内显示28,可读显示28;如果发送的是2条消息56个字节,合并的消息内显示56,可读显示28…以此类推;欢迎大家一起讨论,共同进步,不吝赐教!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值