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

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

解决方案:

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

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

来看server端代码:

public class ServerDecoder {
    public static void main(String[] args) throws Exception {
        //1 第一个线程组,是用于接收 client 端连接的
        EventLoopGroup bossGroup = new NioEventLoopGroup();

        //2 第二个线程组,是用于实际的业务处理操作的
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        //3 创建一个辅助类 ServerBootstrap, 就是对我们的 server 端进行一系列配置
        ServerBootstrap b = new ServerBootstrap();
        // 把两个工作线程组加进来
        b.group(bossGroup, workerGroup)
                // 我要指定使用 NioServerSocketChannel 这种类型的通道
                .channel(NioServerSocketChannel.class)
                // 一定要使用 childHandler 去绑定具体的事件处理器
                .childHandler(new ChannelInitializer<SocketChannel>() {

                    @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 ServerHandlerDecoder());
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 128)
                // 保持连接
                .option(ChannelOption.SO_KEEPALIVE, true);

        // 使用指定的端口进行监听
        ChannelFuture f = b.bind(8765).sync();
        f.channel().closeFuture().sync();
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

注意看意思代码的 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()));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值