Netty进阶——粘包与半包(短链接方式解决粘包问题)
Posted 小志的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty进阶——粘包与半包(短链接方式解决粘包问题)相关的知识,希望对你有一定的参考价值。
目录
一、短链接方式解决粘包问题(代码示例)
1.1、短链接方式解决粘包问题的服务端代码示例
-
服务端代码示例
package com.example.nettytest.netty.day5; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioserverSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import lombok.extern.slf4j.Slf4j; /** * @description: 短链接方式解决粘包 问题服务端示例 * @author: xz */ @Slf4j public class NettyShortConnectServer public static void main(String[] args) new NettyServerTest().start(); void start() NioEventLoopGroup boss = new NioEventLoopGroup(1); NioEventLoopGroup worker = new NioEventLoopGroup(); try ServerBootstrap serverBootstrap = new ServerBootstrap() .channel(NioServerSocketChannel.class) .group(boss, worker) .childHandler(new ChannelInitializer<SocketChannel>() @Override protected void initChannel(SocketChannel ch) throws Exception ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG)); ch.pipeline().addLast(new ChannelInboundHandlerAdapter() //会在连接channel建立成功后,触发active事件 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception log.debug("connected>>>>>>>>>>>>>>>> ", ctx.channel()); super.channelActive(ctx); @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception log.debug("disconnect>>>>>>>>>>>>>>>> ", ctx.channel()); super.channelInactive(ctx); ); ); ChannelFuture channelFuture = serverBootstrap.bind(8080); log.debug(">>>>>>>>>>>>>>>> binding...", channelFuture.channel()); channelFuture.sync(); log.debug(">>>>>>>>>>>>>>>> bound...", channelFuture.channel()); channelFuture.channel().closeFuture().sync(); catch (InterruptedException e) log.error("server error", e); finally boss.shutdownGracefully(); worker.shutdownGracefully(); log.debug(">>>>>>>>>>>>>>>>stoped");
1.2、短链接方式解决粘包问题的客户端代码示例
-
客户端代码示例
package com.example.nettytest.netty.day5; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInitializer; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import lombok.extern.slf4j.Slf4j; /** * @description: 短链接方式解决粘包 问题客户端示例 * @author: xz */ @Slf4j public class NettyShortConnectClient public static void main(String[] args) //1、分 3 次发送 for (int i=0;i<3;i++) send(); private static void send() NioEventLoopGroup worker = new NioEventLoopGroup(); try Bootstrap bootstrap = new Bootstrap() .channel(NioSocketChannel.class) .group(worker) .handler(new ChannelInitializer<SocketChannel>() @Override protected void initChannel(SocketChannel ch) throws Exception log.debug("conneted》》》》》》》》"); ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG)); ch.pipeline().addLast(new ChannelInboundHandlerAdapter() @Override public void channelActive(ChannelHandlerContext ctx) throws Exception log.debug("sending》》》》》》》》"); ByteBuf buffer = ctx.alloc().buffer(); buffer.writeBytes(new byte[]0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); ctx.writeAndFlush(buffer); //2、发完即关 ctx.close(); ); ); ChannelFuture channelFuture = bootstrap.connect("localhost", 8080).sync(); channelFuture.channel().closeFuture().sync(); catch (InterruptedException e) log.error("client error", e); finally //3、关闭NioEventLoopGroup线程 worker.shutdownGracefully();
1.3、分别启动服务端,客户端,查看服务端结果输出
-
先启动服务端
-
再启动客户端
-
再次查看服务端
注:可下图输出结果可知:以短链接的方式,发一个包建立一次连接,这样连接建立到连接断开之间就是消息的边界,解决了粘包问题,但是缺点是效率太低。
以上是关于Netty进阶——粘包与半包(短链接方式解决粘包问题)的主要内容,如果未能解决你的问题,请参考以下文章