Netty5中使用LineBasedFrameDecoder解决TCP粘包问题

来源:互联网 发布:htc g16软件下载 编辑:程序博客网 时间:2024/06/11 19:05

为了解决TCP粘包/拆包导致的半包读写问题,Netty默认提供了多种编解码器用于处理该类问题,本例程将展示Netty中LineBasedFrameDecoder的使用

/** *  */package upup.me.netty.practice02;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;/** * @author Administrator * */public class TimeServer {public void bind(int port) {// 配置服务端的NIO线程组EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap();// 设置线程组及Socket参数b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());// 绑定端口,同步等待成功ChannelFuture f = b.bind(port).sync();System.out.println("服务已经启动,端口:" + port);f.channel().closeFuture().sync();} catch (Exception e) {} finally {// 退出释放线程池资源bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();System.out.println("服务销毁!");}}public static void main(String[] args) {int port = 8080;if (null != args && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (Exception e) {// 采用默认值}}new TimeServer().bind(port);}}

/** *  */package upup.me.netty.practice02;import java.util.Date;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;/** * @author Administrator * */public class TimeServerHandler extends ChannelHandlerAdapter {private int counter;public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {String body = (String) msg;System.out.println("The time server receive order:" + body + ";the counter is:" + (++counter));String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString(): "BAD ORDER";currentTime = currentTime + System.getProperty("line.separator");ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());ctx.write(resp);}public void channelReadComplete(ChannelHandlerContext ctx) {ctx.flush();}public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {ctx.close();}}

/** *  */package upup.me.netty.practice02;import io.netty.channel.ChannelInitializer;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LineBasedFrameDecoder;import io.netty.handler.codec.string.StringDecoder;/** * @author Administrator * */public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 以下两行代码为了解决半包读问题ch.pipeline().addLast(new LineBasedFrameDecoder(1024));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new TimeServerHandler());}}

/** *  */package upup.me.netty.practice02;import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.LineBasedFrameDecoder;import io.netty.handler.codec.string.StringDecoder;/** * @author Administrator * */public class TimeClient {public void connect(int port, String host) {// 配置客户端的NIO线程组EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {// 以下两行代码为了解决半包读问题ch.pipeline().addLast(new LineBasedFrameDecoder(1024));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new TimeClientHandler());}});// 发起异步连接操作ChannelFuture f = b.connect(host, port).sync();// 等待链路关闭f.channel().closeFuture().sync();} catch (Exception e) {} finally {// 退出,释放NIO线程组group.shutdownGracefully();}}public static void main(String[] args) {int port = 8080;if (null != args && args.length > 0) {try {port = Integer.valueOf(args[0]);} catch (Exception e) {}}new TimeClient().connect(port, "127.0.0.1");}}

/** *  */package upup.me.netty.practice02;import java.io.UnsupportedEncodingException;import java.util.logging.Logger;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;/** * @author Administrator * */public class TimeClientHandler extends ChannelHandlerAdapter {private static final Logger logger = Logger.getLogger(TimeClientHandler.class.getName());private int counter;private byte[] req;public TimeClientHandler() {req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes();}public void channelActive(ChannelHandlerContext ctx) {ByteBuf message = null;for (int i = 0; i < 100; i++) {message = Unpooled.buffer(req.length);message.writeBytes(req);ctx.writeAndFlush(message);}}public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {String body = (String) msg;System.out.println("Now is:" + body + "; the counter is:" + (++counter));}public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {logger.warning("Unexcepted exception from downstream:" + cause.getMessage());ctx.close();}}


0 0
原创粉丝点击