DelimiterBasedFrameDecoder使用

DelimiterBasedFrameDecoder是一个分隔符解码器。
FixedLengthFrameDecoder作用和它差不多,只不过是定长。
可以同时接受多个分隔符,第一个参数是缓冲区大小,如果长度超过1024(可以指定),并且没有找到分隔符,则会抛异常。
如果长度小于1024,并且没有找到分隔符,会缓存收到的消息,直到接收到分隔符,或者超出1024抛异常。

ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
                            ByteBuf delimiter0 = Unpooled.copiedBuffer("A".getBytes());
                            ByteBuf delimiter1 = Unpooled.copiedBuffer("B".getBytes());

                            socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter,delimiter0,delimiter1));

同时存在多个分隔符时,优先匹配长度最短的分隔符,如果一样长,则哪个先出现,匹配哪个。

应用示例

服务端

   public static void main(String[] args) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG,100)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
                            ByteBuf delimiter0 = Unpooled.copiedBuffer("A".getBytes());
                            ByteBuf delimiter1 = Unpooled.copiedBuffer("B".getBytes());

                            socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter,delimiter0,delimiter1));
                            socketChannel.pipeline().addLast(new StringDecoder());
                            socketChannel.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            ChannelFuture channelFuture =serverBootstrap.bind(7799).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
public class EchoServerHandler extends SimpleChannelInboundHandler<String> {


    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String o) throws Exception {
        System.out.println(o);
        o +="$_";
        ByteBuf echo = Unpooled.copiedBuffer(o.getBytes());
        channelHandlerContext.writeAndFlush(echo);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

客户端

public class EchoClient {
    public void connect(int port,String host){
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY,true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
//                            ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
//                            socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter));
                            socketChannel.pipeline().addLast(new StringDecoder());
                            socketChannel.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            ChannelFuture channelFuture=b.connect(host,port).sync();
            channelFuture.channel().closeFuture().sync();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        EchoClient echoClient = new EchoClient();
        echoClient.connect(7799,"127.0.0.1");
    }
}

public class EchoClientHandler extends SimpleChannelInboundHandler<String> {
    public static  final String STRINGTAG="HELLO,这是什";
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        for (int i=0;i<10;i++){
            ctx.writeAndFlush(Unpooled.copiedBuffer(STRINGTAG.getBytes()));
            Thread.sleep(3000);
            ctx.writeAndFlush(Unpooled.copiedBuffer("么你A好吗$_不是B".getBytes()));
//            ctx.writeAndFlush(Unpooled.copiedBuffer(new byte[1024]));
//        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String o) throws Exception {
        System.out.println(o);
    }
}
在 Netty4 中,可以使用 `DelimiterBasedFrameDecoder` 类来根据指定的字符串拆包。这个类会将接收到的字节流按照指定的分隔符拆分成多个消息,并且将每个消息自动封装成一个 ByteBuf 对象,然后传递给后续的 ChannelHandler 进行处理。以下是一个示例: ```java ByteBuf delimiter = Unpooled.copiedBuffer("$".getBytes()); ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new DelimiterBasedFrameDecoder(8192, delimiter)); pipeline.addLast(new StringDecoder()); pipeline.addLast(new MyHandler()); ``` 在上面的示例中,我们使用 `$` 作为分隔符,并设置最大消息长度为 8192。接着,我们添加了一个 `StringDecoder`,将接收到的 ByteBuf 对象自动解码成字符串。最后,我们添加了一个自定义的 ChannelHandler `MyHandler` 来处理接收到的消息。 在 `MyHandler` 中,我们可以通过重载 `channelRead` 方法来处理接收到的消息,例如: ```java public class MyHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String message = (String) msg; System.out.println("Received message: " + message); // TODO: 处理消息 } } ``` 当有消息到达时,`channelRead` 方法会被调用,我们可以在这里处理接收到的消息。注意,在使用 `DelimiterBasedFrameDecoder` 时,我们需要保证分隔符不能出现在消息内容中,否则会导致消息拆分错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值