netty demo
Netty 4.0 demo
netty是一个异步,事件驱动的网络编程框架&工具,使用netty,可以快速开发从可维护,高性能的协议服务和客户端应用。是一个继mina之后,一个非常受欢迎的nio网络框架
netty4.x和之前的版本变化很大,包结构、对象和之前有很大不同。原来的包结构都是org.jboss.netty.*;目前改为了io.netty.* 的方式,其中,server,client的对象也和原来不同了
根据4.x的稳定版本4.0.14为蓝本,写一个hello world试试看。值得注意的是,4.0.x的beta版和final版本也有不小调整。很不幸的时,在4.x中刚出现的部分方法,到5.x中也将废弃。哎,苦逼的IT人。废话不说,看个4.x的例子吧
需要说明的是,我用的是netty4.0.13这个版本。因为netty有很多包,大家可以引入这个all包,其他的就全部包括了。
server端代码:
1 package netty.test; 2 3 4 import io.netty.bootstrap.ServerBootstrap; 5 import io.netty.channel.Channel; 6 import io.netty.channel.ChannelFuture; 7 import io.netty.channel.ChannelInitializer; 8 import io.netty.channel.ChannelPipeline; 9 import io.netty.channel.EventLoopGroup; 10 import io.netty.channel.nio.NioEventLoopGroup; 11 import io.netty.channel.socket.nio.NioServerSocketChannel; 12 import io.netty.handler.codec.LengthFieldBasedFrameDecoder; 13 import io.netty.handler.codec.LengthFieldPrepender; 14 import io.netty.handler.codec.string.StringDecoder; 15 import io.netty.handler.codec.string.StringEncoder; 16 import io.netty.util.CharsetUtil; 17 18 public class MyNettyServer { 19 private static final String IP = "127.0.0.1"; 20 private static final int PORT = 5656; 21 private static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2; 22 23 private static final int BIZTHREADSIZE = 100; 24 private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE); 25 private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE); 26 public static void service() throws Exception { 27 ServerBootstrap bootstrap = new ServerBootstrap(); 28 bootstrap.group(bossGroup, workerGroup); 29 bootstrap.channel(NioServerSocketChannel.class); 30 bootstrap.childHandler(new ChannelInitializer<Channel>() { 31 32 @Override 33 protected void initChannel(Channel ch) throws Exception { 34 // TODO Auto-generated method stub 35 ChannelPipeline pipeline = ch.pipeline(); 36 pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); 37 pipeline.addLast(new LengthFieldPrepender(4)); 38 pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); 39 pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); 40 pipeline.addLast(new TcpServerHandler()); 41 } 42 43 }); 44 ChannelFuture f = bootstrap.bind(IP, PORT).sync(); 45 f.channel().closeFuture().sync(); 46 System.out.println("TCP服务器已启动"); 47 } 48 49 protected static void shutdown() { 50 workerGroup.shutdownGracefully(); 51 bossGroup.shutdownGracefully(); 52 } 53 54 public static void main(String[] args) throws Exception { 55 System.out.println("开始启动TCP服务器..."); 56 MyNettyServer.service(); 57 // HelloServer.shutdown(); 58 } 59 }
对应的Handler对象 TcpServerHandler.java
1 package netty.test; 2 3 import io.netty.channel.ChannelHandlerAdapter; 4 import io.netty.channel.ChannelHandlerContext; 5 import io.netty.channel.ChannelInboundHandlerAdapter; 6 7 public class TcpServerHandler extends ChannelInboundHandlerAdapter { 8 9 10 @Override 11 public void channelRead(ChannelHandlerContext ctx, Object msg) 12 throws Exception { 13 // TODO Auto-generated method stub 14 System.out.println("server receive message :"+ msg); 15 ctx.channel().writeAndFlush("yes server already accept your message" + msg); 16 ctx.close(); 17 } 18 @Override 19 public void channelActive(ChannelHandlerContext ctx) throws Exception { 20 // TODO Auto-generated method stub 21 System.out.println("channelActive>>>>>>>>"); 22 } 23 @Override 24 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 25 System.out.println("exception is general"); 26 } 27 }
客户端代码:
1 package netty.test; 2 3 import io.netty.bootstrap.Bootstrap; 4 import io.netty.channel.ChannelFuture; 5 import io.netty.channel.ChannelInitializer; 6 import io.netty.channel.ChannelOption; 7 import io.netty.channel.ChannelPipeline; 8 import io.netty.channel.EventLoopGroup; 9 import io.netty.channel.nio.NioEventLoopGroup; 10 import io.netty.channel.socket.SocketChannel; 11 import io.netty.channel.socket.nio.NioSocketChannel; 12 import io.netty.handler.codec.LengthFieldBasedFrameDecoder; 13 import io.netty.handler.codec.LengthFieldPrepender; 14 import io.netty.handler.codec.string.StringDecoder; 15 import io.netty.handler.codec.string.StringEncoder; 16 import io.netty.util.CharsetUtil; 17 18 public class NettyClient implements Runnable { 19 20 @Override 21 public void run() { 22 EventLoopGroup group = new NioEventLoopGroup(); 23 try { 24 Bootstrap b = new Bootstrap(); 25 b.group(group); 26 b.channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true); 27 b.handler(new ChannelInitializer<SocketChannel>() { 28 @Override 29 protected void initChannel(SocketChannel ch) throws Exception { 30 ChannelPipeline pipeline = ch.pipeline(); 31 pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); 32 pipeline.addLast("frameEncoder", new LengthFieldPrepender(4)); 33 pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8)); 34 pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8)); 35 36 pipeline.addLast("handler", new HelloClient()); 37 } 38 }); 39 for (int i = 0; i < 100000; i++) { 40 ChannelFuture f = b.connect("127.0.0.1", 5656).sync(); 41 f.channel().writeAndFlush("hello Service!"+Thread.currentThread().getName()+":--->:"+i); 42 f.channel().closeFuture().sync(); 43 } 44 45 46 } catch (Exception e) { 47 48 } finally { 49 group.shutdownGracefully(); 50 } 51 } 52 53 public static void main(String[] args) throws Exception { 54 for (int i = 0; i < 1000; i++) { 55 new Thread(new NettyClient(),">>>this thread "+i).start(); 56 } 57 } 58 }
客户端对应的Handler对象代码,HelloClient.java
package netty.test; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class HelloClient extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("client接收到服务器返回的消息:" + msg); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("client exception is general"); } }