Netty Serial 3:分隔符解码器的应用

一:分隔符解码器简介
  在 http://chenjunfei0617.iteye.com/blog/2244947中已经介绍了Netty自带的两种解码器,这一节为大家介绍一个Netty自带的一种分隔符解码器DelimiterBasedFrameDecoder。分隔符解码器顾名思义就是完成以分隔符作为结束标志的消息的解码。

二:分隔符解码器的应用
  本节以Echo服务为例,为大家介绍分隔符解码器的应用。

1、EchoServer
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
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.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * 分隔符解码器的实现
 * 
 * @author chenjf
 *
 */
public class EchoServer {
	public void bind(int port) {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
					.option(ChannelOption.SO_BACKLOG, 100)// .handler(new
															// LoggerHandler())
					.childHandler(new ChannelInitializer<SocketChannel>() {
						protected void initChannel(SocketChannel cp) throws Exception {
							ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
							cp.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
							cp.pipeline().addLast(new StringDecoder());
							cp.pipeline().addLast(new EchoServerHandler());
						};
					});
			ChannelFuture f = bootstrap.bind(port).sync();
			f.channel().closeFuture().sync();
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) {
		new EchoServer().bind(8080);
	}
}


2、EchoServerHandler
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoServerHandler extends ChannelHandlerAdapter {

	private int count = 0;

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		// TODO Auto-generated method stub
		String body = (String) msg;
		System.out.println("this is " + ++count + " times receive client :" + body);
		body += "$_";
		ByteBuf echo = Unpooled.copiedBuffer(body.getBytes());
		ctx.writeAndFlush(echo);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		// TODO Auto-generated method stub
		cause.printStackTrace();
		ctx.close();
	}

}


3、EchoClient
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
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.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;

public class EchoClient {
	public void connect(String host, int port) {
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			Bootstrap bootstrap = new Bootstrap();
			bootstrap.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
					.handler(new ChannelInitializer<SocketChannel>() {
						protected void initChannel(SocketChannel s) throws Exception {
							ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes());
							s.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter));
							s.pipeline().addLast(new StringDecoder());
							s.pipeline().addLast(new EchoClienHandler());
						};
					});
			ChannelFuture f = bootstrap.connect(host, port).sync();

			f.channel().closeFuture().sync();
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			group.shutdownGracefully();
		}
	}

	public static void main(String[] args) {
		new EchoClient().connect("localhost", 8080);
	}
}


4、EchoClienHandler
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoClienHandler extends ChannelHandlerAdapter {

	private int count = 0;

	public static final String req = "hello,welcome to netty.$_";

	public EchoClienHandler() {

	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		for (int i = 0; i < 10; i++) {
			ctx.writeAndFlush(Unpooled.copiedBuffer(req.getBytes()));
		}
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("this is " + ++count + " times receive server :" + msg);
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		// TODO Auto-generated method stub
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		// TODO Auto-generated method stub
		ctx.close();
	}
}


运行结果如下:
服务器端:
this is 1 times receive client :hello,welcome to netty.
this is 2 times receive client :hello,welcome to netty.
this is 3 times receive client :hello,welcome to netty.
this is 4 times receive client :hello,welcome to netty.
this is 5 times receive client :hello,welcome to netty.
this is 6 times receive client :hello,welcome to netty.
this is 7 times receive client :hello,welcome to netty.
this is 8 times receive client :hello,welcome to netty.
this is 9 times receive client :hello,welcome to netty.
this is 10 times receive client :hello,welcome to netty.

客户端:
this is 1 times receive server :hello,welcome to netty.
this is 2 times receive server :hello,welcome to netty.
this is 3 times receive server :hello,welcome to netty.
this is 4 times receive server :hello,welcome to netty.
this is 5 times receive server :hello,welcome to netty.
this is 6 times receive server :hello,welcome to netty.
this is 7 times receive server :hello,welcome to netty.
this is 8 times receive server :hello,welcome to netty.
this is 9 times receive server :hello,welcome to netty.
this is 10 times receive server :hello,welcome to netty.

猜你喜欢

转载自chenjunfei0617.iteye.com/blog/2246700