DelimiterBasedFrameDecoder
以分隔符作为码流结束标识的消息的解码
示例:Echo服务,以$_作为分隔符
EchoServer.java关键代码
@Override
public void initChannel(SocketChannel ch) throws Exception{
//创建分隔符缓冲对象ByteBuf,以$_为分隔符
ByteBuf delimiter=Unpooled.copiedBuffer("$_".getBytes());
//1024表示单条消息的最大长度,当达到该长度后仍然没有查找到分隔符
//就抛出TooLongFrameException异常
//第二个参数是分隔符缓冲对象
new DelimiterBasedFrameDecoder(1024,delimiter)); //后续的ChannelHandler接收到的msg对象将会是完整的消息包
ch.pipeline().addLast(new StringDecoder()); //将ByteBuf解码成字符串对象
ch.pipeline().addLast(new EchoServerHandler()); //接收到的msg消息就是解码后的字符串对象
}
EchoServerHandler.java 关键代码
@Override
public void channelRead(ChannelHandlerContext ctx,Object msg) throws Exception{
String body=(String)msg;
System.out.println("This is " + ++counter + " times receive client : [" + body + "]");
body+="$_"; //$_已被过滤掉了,所以这里要拼接上
ByteBuf echo = Unpooled.copiedBuffer(body.getBytes());
ctx.writeAndFlush(echo);
}
EchoClient.java 关键代码
@Override
public void initChannel(SocketChannel ch) throws Exception{
ByteBuf delimiter=Unpooled.copiedBuffer("$_".getBytes());
ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,delimiter));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new EchoClientHandler());
}
EchoClientHandler.java 关键代码
@Override
public void channelActive(ChannelHandlerContext ctx){
for(int i=0;i<10;i++){
ctx.writeAndFlush(Unpooled.copiedBuffer(ECHOREQ.getBytes()));
}
}
FixedLengthFrameDecoder应用开发
固定长度解码器,按照指定的长度对消息进行自动解码,开发者不需要考虑TCP的粘包/拆包问题
示例仍是Echo服务
EchoServer.java 关键代码
@Override
public void initChannel (SocketChannel ch) throws Exception{
ch.pipeline().addLast(new FixedLengthFrameDecoder(20));
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new EchoServerHandler()));
}
EchoServerHandler.java 关键代码
@Override
public void channelRead(ChannelHandlerContext ctx,Object msg) throws Exception{
System.out.println("Receive client : [" + msg + "]");
}