Netty学习笔记:2
2015-07-18 13:06
381 查看
1、TCP粘包/拆包
概念是什么?
TCP是个“流”协议,所谓流,就是没有界限的一串数据。
而一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个包封装成一个大的数据包发送,这就是所谓TCP,粘包/拆包
流可以被抽象理解成一条和,那粘包就是两个数据在河流里面贴在一起,而拆包就是一个数据在河流里面被分成两截。
2、成因和解决策略
成因感觉很好理解,想象一下就行。
解决方案直接上代码,是对上一篇文章所载代码的改进。
这个例子对比于上一章,只改变了这俩Handler文件,在客户端那个类,25行到28行,循环发送了100条消息,每发送一条就刷新一次,按照初衷应该打印100条查询时间命令的请求消息。
可是结果是这样的。
也就是说只发送了两次。
这说明发生了粘包
关于TCP粘包/拆包导致的半包读写问题,Netty默认提供了,多种编解码器用于处理半包。
下面是解决了TCP粘包的TimeServer和TimeClient
package com.ftrend.netty.release3;
import io.netty.bootstrap.ServerBootstrap;
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.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
public class TimeServer {
public void bind(int port) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,1024)
.childHandler(new ChildChannelHandler());
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel arg0) throws Exception {
arg0.pipeline().addLast(new LineBasedFrameDecoder(1024));
arg0.pipeline().addLast(new StringDecoder());
arg0.pipeline().addLast(new TimeServerHandler());
}
}
public static void main(String[] args) throws Exception {
new TimeServer().bind(39998);
}
}
其实就是加了编码解码的代码,然后在Handler中删除编码解码的代码
arg0.pipeline().addLast(new LineBasedFrameDecoder(1024));
arg0.pipeline().addLast(new StringDecoder());
运行后的结果也大大
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 1
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 2
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 3
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 4
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 5
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 6
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 7
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 8
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 9
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 10
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 11
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 12
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 13
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 14
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 15
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 16
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 17
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 18
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 19
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 20
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 21
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 22
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 23
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 24
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 25
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 26
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 27
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 28
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 29
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 30
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 31
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 32
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 33
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 34
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 35
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 36
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 37
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 38
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 39
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 40
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 41
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 42
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 43
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 44
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 45
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 46
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 47
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 48
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 49
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 50
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 51
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 52
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 53
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 54
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 55
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 56
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 57
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 58
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 59
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 60
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 61
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 62
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 63
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 64
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 65
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 66
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 67
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 68
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 69
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 70
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 71
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 72
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 73
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 74
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 75
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 76
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 77
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 78
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 79
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 80
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 81
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 82
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 83
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 84
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 85
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 86
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 87
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 88
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 89
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 90
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 91
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 92
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 93
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 94
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 95
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 96
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 97
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 98
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 99
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 100
这说明LineBasedFrameDecoder和StringDecoder解决了粘包拆包问题。
最后解释一下为什么
LineBasedFrameDecoder就是以换行符作为结束标志的解码器,
而StringDecoder仅仅是简单的编码成String
还有两种解码器
分隔符解码器:DelimierBasedFrameDecoder
定长解码器:FixedLengthFrameDecoder
概念是什么?
TCP是个“流”协议,所谓流,就是没有界限的一串数据。
而一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个包封装成一个大的数据包发送,这就是所谓TCP,粘包/拆包
流可以被抽象理解成一条和,那粘包就是两个数据在河流里面贴在一起,而拆包就是一个数据在河流里面被分成两截。
2、成因和解决策略
成因感觉很好理解,想象一下就行。
解决方案直接上代码,是对上一篇文章所载代码的改进。
package com.ftrend.netty.release2; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; public class TimeServerHandler extends ChannelHandlerAdapter { private int counter; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf) msg; byte[] req = new byte[buf.readableBytes()]; buf.readBytes(req); String body = new String(req, "UTF-8").substring(0, req.length - System.getProperty("line.separator").length()); System.out.println("The time server recevie order : " + body + " ; the counter is : " + ++counter); String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()) .toString() : "BAD ORDER"; currentTime = currentTime + System.getProperty("line.separator"); ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes()); ctx.writeAndFlush(resp); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
package com.ftrend.netty.release2; 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; public class TimeCilentHandler extends ChannelHandlerAdapter { private static final Logger logger = Logger.getLogger(TimeCilentHandler.class.getName()); private int counter; private byte[] req; public TimeCilentHandler(){ req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes(); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ByteBuf message = null; for(int i = 0; i < 100; i++){ message = Unpooled.buffer(req.length); message.writeBytes(req); ctx.writeAndFlush(message); } } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf buf = (ByteBuf)msg; byte[] req = new byte[buf.readableBytes()]; buf.readBytes(req); String body = new String(req,"UTF-8"); System.out.println("Now is : " + body + " ;the counter is : " + ++counter); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.warning("Unexpected exception from downstream : " + cause.getMessage()); ctx.close(); } public static void main(String[] args) { } }
这个例子对比于上一章,只改变了这俩Handler文件,在客户端那个类,25行到28行,循环发送了100条消息,每发送一条就刷新一次,按照初衷应该打印100条查询时间命令的请求消息。
可是结果是这样的。
The time server recevie order : QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORD ; the counter is : 1 The time server recevie order : QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER QUERY TIME ORDER ; the counter is : 2
也就是说只发送了两次。
这说明发生了粘包
关于TCP粘包/拆包导致的半包读写问题,Netty默认提供了,多种编解码器用于处理半包。
下面是解决了TCP粘包的TimeServer和TimeClient
package com.ftrend.netty.release3;
import io.netty.bootstrap.ServerBootstrap;
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.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
public class TimeServer {
public void bind(int port) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG,1024)
.childHandler(new ChildChannelHandler());
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel arg0) throws Exception {
arg0.pipeline().addLast(new LineBasedFrameDecoder(1024));
arg0.pipeline().addLast(new StringDecoder());
arg0.pipeline().addLast(new TimeServerHandler());
}
}
public static void main(String[] args) throws Exception {
new TimeServer().bind(39998);
}
}
package com.ftrend.netty.release3; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; public class TimeServerHandler extends ChannelHandlerAdapter { private int counter; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String body = (String)msg; System.out.println("The time server recevie order : " + body + " ; the counter is : " + ++counter); String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()) .toString() : "BAD ORDER"; currentTime = currentTime + System.getProperty("line.separator"); ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes()); ctx.writeAndFlush(resp); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
package com.ftrend.netty.release3; 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; public class TimeClient { public void connect(int port, String host) throws Exception{ 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 protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new LineBasedFrameDecoder(1024)); ch.pipeline().addLast(new StringDecoder()); ch.pipeline().addLast(new TimeCilentHandler()); } }); ChannelFuture f = b.connect(host, port).sync(); f.channel().closeFuture().sync(); }finally{ group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new TimeClient().connect(39998, "127.0.0.1"); } }
package com.ftrend.netty.release3; 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; public class TimeCilentHandler extends ChannelHandlerAdapter { private static final Logger logger = Logger.getLogger(TimeCilentHandler.class.getName()); private int counter; private byte[] req; public TimeCilentHandler(){ req = ("QUERY TIME ORDER" + System.getProperty("line.separator")).getBytes(); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ByteBuf message = null; for(int i = 0; i < 100; i++){ message = Unpooled.buffer(req.length); message.writeBytes(req); ctx.writeAndFlush(message); } } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String body = (String)msg; System.out.println("Now is : " + body + " ;the counter is : " + ++counter); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.warning("Unexpected exception from downstream : " + cause.getMessage()); ctx.close(); } }
其实就是加了编码解码的代码,然后在Handler中删除编码解码的代码
arg0.pipeline().addLast(new LineBasedFrameDecoder(1024));
arg0.pipeline().addLast(new StringDecoder());
运行后的结果也大大
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 1
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 2
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 3
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 4
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 5
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 6
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 7
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 8
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 9
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 10
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 11
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 12
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 13
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 14
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 15
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 16
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 17
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 18
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 19
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 20
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 21
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 22
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 23
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 24
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 25
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 26
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 27
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 28
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 29
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 30
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 31
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 32
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 33
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 34
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 35
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 36
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 37
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 38
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 39
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 40
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 41
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 42
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 43
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 44
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 45
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 46
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 47
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 48
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 49
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 50
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 51
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 52
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 53
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 54
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 55
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 56
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 57
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 58
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 59
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 60
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 61
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 62
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 63
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 64
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 65
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 66
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 67
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 68
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 69
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 70
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 71
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 72
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 73
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 74
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 75
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 76
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 77
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 78
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 79
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 80
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 81
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 82
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 83
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 84
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 85
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 86
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 87
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 88
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 89
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 90
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 91
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 92
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 93
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 94
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 95
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 96
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 97
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 98
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 99
Now is : Sat Jul 18 14:25:18 CST 2015 ;the counter is : 100
这说明LineBasedFrameDecoder和StringDecoder解决了粘包拆包问题。
最后解释一下为什么
LineBasedFrameDecoder就是以换行符作为结束标志的解码器,
而StringDecoder仅仅是简单的编码成String
还有两种解码器
分隔符解码器:DelimierBasedFrameDecoder
定长解码器:FixedLengthFrameDecoder
相关文章推荐
- jsp-DB
- Paper List ABOUT Deep Learning
- ZOJ Monthly, June 2014部分题解
- c++Builder 2009 2010 出现Cannot convert 'wchar_t *' to 'const char *
- 收藏 - 随时更新
- 构造 Codeforces Round #107 (Div. 2) B. Phone Numbers
- 3Sum Closest
- 完整版:《开源框架实战宝典电子书V1.0.0》内测版下载地址!
- win8让触摸键盘透明
- 类的加载、执行顺序
- stm32操作时钟芯片ds1390
- Java Web开发之:ModelDriven
- Cordys JAVA Object理解
- [译]用R语言做挖掘数据《七》
- 整数实现翻转---java实现
- js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
- rsync+inotify实现数据的实时同步
- Tkinter 控件详细介绍
- HDU 4870 Rating (2014 多校联合第一场 J)(概率)
- 开源完整版:《开源框架实战宝典电子书V1.0.0》内测版下载地址!