Netty使用LineBasedFrameDecoder解决粘包问题
2017-06-01 21:19
651 查看
Netty使用LineBasedFrameDecoder解决粘包问题
问题代码:服务:
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,1024).childHandler(new TimeServerHandler()); ChannelFuture channelFuture = serverBootstrap.bind(6010).sync(); channelFuture.channel().closeFuture().sync(); }catch (Exception e){ e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }
handler:
public class TimeServerHandler extends SimpleChannelInboundHandler<Object> { private int count; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf) msg; byte[] bytes = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(bytes); System.out.println(new String(bytes)); // String str = "hello client**"; System.out.println("receive one msg.count="+ ++count); ByteBuf whriteByteBuf = Unpooled.copiedBuffer(str.getBytes()); ctx.write(whriteByteBuf); // super.channelRead(ctx, msg); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); // super.channelReadComplete(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // super.exceptionCaught(ctx, cause); cause.printStackTrace(); ctx.close(); } @Override protected void channelRead0(ChannelHandlerContext arg0, Object arg1) throws Exception { } }
客户:
public class TimeClient { public static void main(String[] args) throws Exception { int port = 6010; EventLoopGroup workGroup = new NioEventLoopGroup(); try{ Bootstrap bootstrap = new Bootstrap(); bootstrap.group(workGroup).channel(NioSocketChannel.class) .option(ChannelOption.SO_KEEPALIVE,true) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new TimeClientHandler()); } }); ChannelFuture channelFuture = bootstrap.connect("localhost",port).sync(); channelFuture.channel().closeFuture().sync(); }finally { workGroup.shutdownGracefully(); } } }
handler:
public class TimeClientHandler extends SimpleChannelInboundHandler<Object> { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String msg = "hello server"; for(int i = 0; i < 100; i++){ //注意这里每次byteBuf都要重新生成。 ByteBuf byteBuf = Unpooled.buffer(msg.length()); byteBuf.writeBytes(msg.getBytes()); ctx.writeAndFlush(byteBuf); } // super.channelActive(ctx); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf) msg; byte[] bytes = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(bytes); System.out.println(new String(bytes)+"client888"); // super.channelRead(ctx, msg); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { super.channelReadComplete(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } @Override protected void channelRead0(ChannelHandlerContext arg0, Object arg1) throws Exception { } }
服务端运行:
客户端运行:
看到服务端只收到了27条客户端传递过来的数据,应该是有100条才对,可以看出此处发生了TCP粘包。
接下来使用Netty里的LineBasedFrameDecoder来解决此问题。
同样新的服务端:
public class TimeServer { 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,1024) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024)); socketChannel.pipeline().addLast(new TimeServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind(7601).sync(); channelFuture.channel().closeFuture().sync(); }catch (Exception e){ e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
新的客户端:
public class TimeClient { public static void main(String[] args) throws Exception { int port = 7601; EventLoopGroup workGroup = new NioEventLoopGroup(); try{ Bootstrap bootstrap = new Bootstrap(); bootstrap.group(workGroup).channel(NioSocketChannel.class) .option(ChannelOption.SO_KEEPALIVE,true) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new LineBasedFrameDecoder(1024)); socketChannel.pipeline().addLast(new TimeClientHandler()); } });//这里就是用ChannelInitializer来处理的。 ChannelFuture channelFuture = bootstrap.connect("localhost",port).sync(); channelFuture.channel().closeFuture().sync(); }finally { workGroup.shutdownGracefully(); } } }
两者的Handler类代码不变。 服务端输出:
客户端输出:
发现TCP粘包问题已经解决。
相关文章推荐
- Netty5中使用LineBasedFrameDecoder解决TCP粘包问题
- TCP粘包/拆包--利用LineBasedFrameDecoder解决TCP粘包问题
- Netty2:粘包/拆包问题与使用LineBasedFrameDecoder的解决方案
- java netty使用DelimiterBasedFrameDecoder处理tcp粘包问题
- 《netty权威指南》4.3利用LineBasedFrameDecoder解决TCP粘包问题
- 利用LineBasedFrameDecoder解决TCP粘包问题
- TCP粘包/拆包--利用DelimiterBasedFrameDecoder解决TCP粘包问题
- netty 拆包粘包(LineBasedFrameDecoder)
- netty5.0通过LineBasedFrameDecoder和StringDecoder解决粘包
- netty 过长内容分成了多次发送 问题 LengthFieldBasedFrameDecoder使用
- LineBasedFrameDecoder,FixedLengthFrameDecoder,DelimiterBasedFrameDecoder使用详解
- netty LengthFieldBasedFrameDecoder 使用实例
- netty——LengthFieldBasedFrameDecoder实例(解决半包)
- Netty LengthFieldBasedFrameDecoder使用场景分析
- 过长内容分成了多次发送 问题 LengthFieldBasedFrameDecoder使用
- Netty的LengthFieldBasedFrameDecoder使用
- TCP粘包/拆包--利用FixedLengthFrameDecoder解决TCP粘包问题
- Netty解决粘包问题(1) 自定义分隔符
- netty5 LengthFieldBasedFrameDecoder实例(解决半包)
- Netty解决半包(TCP粘包/拆包导致)读写问题