• netty怎么解决拆包粘包的问题


    我们首先看一下什么是拆包粘包:

    解决方案:

    这里面前两种netty是帮我们实现了的

    我们在netty中如何解决呢?我们通过设置特殊分隔符,然后传递数据的时候,把特殊分隔符放到最后即可:

    来看server端代码:

    1. public class ServerDecoder {
    2. public static void main(String[] args) throws Exception {
    3. //1 第一个线程组,是用于接收 client 端连接的
    4. EventLoopGroup bossGroup = new NioEventLoopGroup();
    5. //2 第二个线程组,是用于实际的业务处理操作的
    6. EventLoopGroup workerGroup = new NioEventLoopGroup();
    7. //3 创建一个辅助类 ServerBootstrap, 就是对我们的 server 端进行一系列配置
    8. ServerBootstrap b = new ServerBootstrap();
    9. // 把两个工作线程组加进来
    10. b.group(bossGroup, workerGroup)
    11. // 我要指定使用 NioServerSocketChannel 这种类型的通道
    12. .channel(NioServerSocketChannel.class)
    13. // 一定要使用 childHandler 去绑定具体的事件处理器
    14. .childHandler(new ChannelInitializer() {
    15. @Override
    16. protected void initChannel(SocketChannel sc) throws Exception {
    17. // 设置特殊分隔符
    18. ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
    19. sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
    20. // 设置字符串形式的解码
    21. sc.pipeline().addLast(new StringDecoder());
    22. sc.pipeline().addLast(new ServerHandlerDecoder());
    23. }
    24. })
    25. .option(ChannelOption.SO_BACKLOG, 128)
    26. // 保持连接
    27. .option(ChannelOption.SO_KEEPALIVE, true);
    28. // 使用指定的端口进行监听
    29. ChannelFuture f = b.bind(8765).sync();
    30. f.channel().closeFuture().sync();
    31. bossGroup.shutdownGracefully();
    32. workerGroup.shutdownGracefully();
    33. }
    34. }

    注意看意思代码的 initChannel 方法

    initChannel方法改成这样:
    @Override
    protected void initChannel(SocketChannel sc) throws Exception {
        // 设置特殊分隔符, 
        ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
        sc.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
        // 设置字符串形式的解码
        sc.pipeline().addLast(new StringDecoder());
        sc.pipeline().addLast(new ServerHandler());
    }
    

    以上代码注意要区分先后顺序,一定要先是 DelimiterBasedFrameDecoder, 再到, StringDecoder,

    最后才是我们自己的业务处理逻辑 ServerHandler

    client端的initChannel方法改如下:

    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ByteBuf buf = Unpooled.copiedBuffer("$_".getBytes());
        socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));
        // 设置字符串形式的解码
        socketChannel.pipeline().addLast(new StringDecoder());
        socketChannel.pipeline().addLast(new ClientHandler());
    }

    连接时的代码如下:

    ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync();
    cf1.channel().writeAndFlush(Unpooled.copiedBuffer("bbbbb$_".getBytes()));
    cf1.channel().writeAndFlush(Unpooled.copiedBuffer("ccc$_".getBytes()));
  • 相关阅读:
    有效预警6要素:亿级调用量的阿里云弹性计算SRE实践
    Spring源码解析(十一):spring事务配置类源码
    2022谷粒商城学习笔记(二十一)购物车相关功能
    算法工程师面经汇总
    python 入门到精通(一)
    编码技巧——@KafkaListener的使用
    Java学习总结(答案版)
    MySQL之视图
    MindSearch:AI 时代的“思考型”搜索引擎
    厨卫家居企业应该开展那些线上营销如何开展?
  • 原文地址:https://blog.csdn.net/a826193310/article/details/101076121