Netty5中使用LineBasedFrameDecoder解决TCP粘包问题
2015-08-22 21:55
786 查看
为了解决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> { @Override protected 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>() { @Override public 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(); } } publi ac12 c 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(); } }
相关文章推荐
- 基于递归神经网络的人脸识别探究
- MFC基于socket的网络聊天室的实现
- 初学三种神经网络(前馈,竞争,递归联想存储网络)
- 学习tcl的几个好网络连接
- iOS开发——网络篇——JSON和XML,NSJSONSerialization ,NSXMLParser(XML解析器),NSXMLParserDelegate,MJExtension (字典转模型),GDataXML(三方框架解析XML)
- https实现的几个问题
- Python3.X 抓取网络资源
- hdu1532网络流
- virtualBox 上centos的网络配置 桥接方式(bridge)
- 为什么有了可靠地TCP还需要不可靠的UDP
- UNIX域套接字及TCP、UDP示例
- redis网络超时问题分析
- android 使用OkHttp上传多张图片
- socket编程--TCP客户/服务器模型 (c/s)及基本函数
- Util:Http请求的工具类
- HTTP状态详解
- 正则表达式——速查表(挖坑,本文内容来自网络)
- servlet生命周期详解
- 网络的五层协议体系---互联网协议入门
- TCP/IP-UDP