Netty学习:搭建一个简单的Netty服务(JAVA NIO 类库的异步通信框架)

http://wosyingjun.iteye.com/blog/2303296

Netty学习:搭建一个简单的Netty服务

Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。Netty 已逐渐成为 Java NIO 编程的首选框架。

项目官方地址:http://netty.io/index.html

一. Netty 的优点:

  • API 使用简单,开发门槛低;
  • 功能强大,预置了多种编解码功能,支持多种主流协议;
  • 定制能力强,可以通过 ChannelHandler 对通信框架进行灵活的扩展;
  • 性能高,通过与其它业界主流的 NIO 框架对比,Netty 的综合性能最优;
  • 社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会被加入;
  • 经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它完全满足不同行业的商用标准。

二. 搭建Netty服务:

  1. 添加pom依赖
    Pom代码  收藏代码
    1. <dependency>  
    2.     <groupId>io.netty</groupId>  
    3.     <artifactId>netty-all</artifactId>  
    4.     <version>4.1.0.Final</version>  
    5. </dependency>  
     
  2. SimpleServer(服务端)
    Java代码  收藏代码
    1. package com.yingjun.netty.server;  
    2.   
    3. import io.netty.bootstrap.ServerBootstrap;  
    4. import io.netty.channel.ChannelFuture;  
    5. import io.netty.channel.ChannelInitializer;  
    6. import io.netty.channel.ChannelOption;  
    7. import io.netty.channel.EventLoopGroup;  
    8. import io.netty.channel.nio.NioEventLoopGroup;  
    9. import io.netty.channel.socket.SocketChannel;  
    10. import io.netty.channel.socket.nio.NioServerSocketChannel;  
    11.   
    12. /** 
    13.  *  
    14.  * Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输, 
    15.  * 例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。 
    16.  *  
    17.  */  
    18. public class SimpleServer {  
    19.     private int port;  
    20.   
    21.     public SimpleServer(int port) {  
    22.         this.port = port;  
    23.     }  
    24.   
    25.     public void run() throws Exception {  
    26.         //EventLoopGroup是用来处理IO操作的多线程事件循环器  
    27.         //bossGroup 用来接收进来的连接  
    28.         EventLoopGroup bossGroup = new NioEventLoopGroup();   
    29.         //workerGroup 用来处理已经被接收的连接  
    30.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
    31.         try {  
    32.             //启动 NIO 服务的辅助启动类  
    33.             ServerBootstrap b = new ServerBootstrap();   
    34.             b.group(bossGroup, workerGroup)  
    35.                 //配置 Channel  
    36.                 .channel(NioServerSocketChannel.class)  
    37.                 .childHandler(new ChannelInitializer<SocketChannel>() {   
    38.                         @Override  
    39.                         public void initChannel(SocketChannel ch) throws Exception {  
    40.                             // 注册handler    
    41.                             ch.pipeline().addLast(new SimpleServerHandler());  
    42.                         }  
    43.                     })  
    44.                 .option(ChannelOption.SO_BACKLOG, 128)   
    45.                 .childOption(ChannelOption.SO_KEEPALIVE, true);   
    46.   
    47.             // 绑定端口,开始接收进来的连接  
    48.             ChannelFuture f = b.bind(port).sync();  
    49.             // 等待服务器 socket 关闭 。  
    50.             f.channel().closeFuture().sync();  
    51.         } finally {  
    52.             workerGroup.shutdownGracefully();  
    53.             bossGroup.shutdownGracefully();  
    54.         }  
    55.     }  
    56.       
    57.     public static void main(String[] args) throws Exception {  
    58.         new SimpleServer(9999).run();  
    59.     }  
    60. }  
     
  3. SimpleServerHandler(服务端请求处理Handler)
    Java代码  收藏代码
    1. package com.yingjun.netty.server;  
    2.   
    3. import io.netty.buffer.ByteBuf;  
    4. import io.netty.channel.ChannelHandlerContext;  
    5. import io.netty.channel.ChannelInboundHandlerAdapter;  
    6.   
    7. public class SimpleServerHandler extends ChannelInboundHandlerAdapter {  
    8.   
    9.     @Override  
    10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
    11.         System.out.println("SimpleServerHandler.channelRead");  
    12.         ByteBuf result = (ByteBuf) msg;  
    13.         byte[] result1 = new byte[result.readableBytes()];  
    14.         // msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中  
    15.         result.readBytes(result1);  
    16.         String resultStr = new String(result1);  
    17.         // 接收并打印客户端的信息  
    18.         System.out.println("Client said:" + resultStr);  
    19.         // 释放资源,这行很关键  
    20.         result.release();  
    21.   
    22.         // 向客户端发送消息  
    23.         String response = "hello client!";  
    24.         // 在当前场景下,发送的数据必须转换成ByteBuf数组  
    25.         ByteBuf encoded = ctx.alloc().buffer(4 * response.length());  
    26.         encoded.writeBytes(response.getBytes());  
    27.         ctx.write(encoded);  
    28.         ctx.flush();  
    29.     }  
    30.   
    31.     @Override  
    32.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
    33.         // 当出现异常就关闭连接  
    34.         cause.printStackTrace();  
    35.         ctx.close();  
    36.     }  
    37.   
    38.     @Override  
    39.     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
    40.         ctx.flush();  
    41.     }  
    42.   
    43. }  
     
  4. SimpleServer(客户端)
    Java代码  收藏代码
    1. package com.yingjun.netty.server;  
    2.   
    3. import io.netty.bootstrap.Bootstrap;  
    4. import io.netty.bootstrap.ServerBootstrap;  
    5. import io.netty.channel.ChannelFuture;  
    6. import io.netty.channel.ChannelInitializer;  
    7. import io.netty.channel.ChannelOption;  
    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.NioServerSocketChannel;  
    12. import io.netty.channel.socket.nio.NioSocketChannel;  
    13.   
    14. public class SimpleClient {  
    15.       
    16.     public void connect(String host, int port) throws Exception {  
    17.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
    18.   
    19.         try {  
    20.             Bootstrap b = new Bootstrap();  
    21.             b.group(workerGroup);  
    22.             b.channel(NioSocketChannel.class);  
    23.             b.option(ChannelOption.SO_KEEPALIVE, true);  
    24.             b.handler(new ChannelInitializer<SocketChannel>() {  
    25.                 @Override  
    26.                 public void initChannel(SocketChannel ch) throws Exception {  
    27.                     ch.pipeline().addLast(new SimpleClientHandler());  
    28.                 }  
    29.             });  
    30.   
    31.             // Start the client.  
    32.             ChannelFuture f = b.connect(host, port).sync();  
    33.   
    34.             // Wait until the connection is closed.  
    35.             f.channel().closeFuture().sync();  
    36.         } finally {  
    37.             workerGroup.shutdownGracefully();  
    38.         }  
    39.     }  
    40.       
    41.     public static void main(String[] args) throws Exception {  
    42.         SimpleClient client=new SimpleClient();  
    43.         client.connect("127.0.0.1"9999);  
    44.     }  
    45.       
    46. }  
     
  5. SimpleServerHandler(客户端请求处理Handler)
    Java代码  收藏代码
    1. package com.yingjun.netty.server;  
    2.   
    3. import io.netty.buffer.ByteBuf;  
    4. import io.netty.channel.ChannelHandlerContext;  
    5. import io.netty.channel.ChannelInboundHandlerAdapter;  
    6.   
    7. public class SimpleClientHandler extends ChannelInboundHandlerAdapter {  
    8.   
    9.     @Override  
    10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
    11.         System.out.println("SimpleClientHandler.channelRead");    
    12.         ByteBuf result = (ByteBuf) msg;    
    13.         byte[] result1 = new byte[result.readableBytes()];    
    14.         result.readBytes(result1);    
    15.         System.out.println("Server said:" + new String(result1));    
    16.         result.release();    
    17.     }  
    18.   
    19.     @Override  
    20.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {  
    21.         // 当出现异常就关闭连接  
    22.         cause.printStackTrace();  
    23.         ctx.close();  
    24.     }  
    25.   
    26.       
    27.     // 连接成功后,向server发送消息    
    28.     @Override    
    29.     public void channelActive(ChannelHandlerContext ctx) throws Exception {    
    30.         String msg = "hello Server!";    
    31.         ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());    
    32.         encoded.writeBytes(msg.getBytes());    
    33.         ctx.write(encoded);    
    34.         ctx.flush();    
    35.     }    
    36. }  
     
  6. 运行结果:

    Java代码  收藏代码
    1. SimpleClientHandler.channelRead  
    2. Server said:hello client!  
    3. ------------------------------------------  
    4. SimpleServerHandler.channelRead  
    5. Client said:hello Server!  
    6. SimpleServerHandler.channelRead  
    7. Client said:hello Server! 

阅读更多
换一批

没有更多推荐了,返回首页