java nio框架Netty



 

Java NIO框架Netty简单使用

  3866人阅读  评论(3)  收藏  举报
  分类:

转载请注明出处:http://blog.csdn.net/anxpp/article/details/52108238,谢谢!

    之前写了一篇文章:Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即Java NIO框架。

    Netty是业界最流行的NIO框架之一,具有良好的健壮性、功能、性能、可定制性和可扩展性。同时,它提供的十分简单的API,大大简化了我们的网络编程。

    同Java IO介绍的文章一样,本文所展示的例子,实现了一个相同的功能。

1、服务端

    Server:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.bootstrap.ServerBootstrap;  
  3. import io.netty.channel.ChannelFuture;  
  4. import io.netty.channel.ChannelInitializer;  
  5. import io.netty.channel.ChannelOption;  
  6. import io.netty.channel.EventLoopGroup;  
  7. import io.netty.channel.nio.NioEventLoopGroup;  
  8. import io.netty.channel.socket.SocketChannel;  
  9. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  10. public class Server {  
  11.     private int port;  
  12.     public Server(int port) {  
  13.         this.port = port;  
  14.     }  
  15.     public void run() throws Exception {  
  16.         EventLoopGroup bossGroup = new NioEventLoopGroup();  
  17.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  18.         try {  
  19.             ServerBootstrap b = new ServerBootstrap();  
  20.             b.group(bossGroup, workerGroup)  
  21.              .channel(NioServerSocketChannel.class)  
  22.              .option(ChannelOption.SO_BACKLOG, 1024)  
  23.              .childOption(ChannelOption.SO_KEEPALIVE, true)  
  24.              .childHandler(new ChannelInitializer<SocketChannel>() {  
  25.                  @Override  
  26.                  public void initChannel(SocketChannel ch) throws Exception {  
  27.                      ch.pipeline().addLast(new ServerHandler());  
  28.                  }  
  29.              });  
  30.             ChannelFuture f = b.bind(port).sync();  
  31.             System.out.println("服务器开启:"+port);  
  32.             f.channel().closeFuture().sync();  
  33.         } finally {  
  34.             workerGroup.shutdownGracefully();  
  35.             bossGroup.shutdownGracefully();  
  36.         }  
  37.     }  
  38.     public static void main(String[] args) throws Exception {  
  39.         int port;  
  40.         if (args.length > 0) {  
  41.             port = Integer.parseInt(args[0]);  
  42.         } else {  
  43.             port = 9090;  
  44.         }  
  45.         new Server(port).run();  
  46.     }  
  47. }  

    ServerHandler:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.buffer.ByteBuf;  
  3. import io.netty.buffer.Unpooled;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. import java.io.UnsupportedEncodingException;  
  7. import com.anxpp.io.utils.Calculator;  
  8. public class ServerHandler extends ChannelInboundHandlerAdapter {  
  9.     @Override  
  10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {  
  11.         ByteBuf in = (ByteBuf) msg;  
  12.         byte[] req = new byte[in.readableBytes()];  
  13.         in.readBytes(req);  
  14.         String body = new String(req,"utf-8");  
  15.         System.out.println("收到客户端消息:"+body);  
  16.         String calrResult = null;  
  17.         try{  
  18.             calrResult = Calculator.Instance.cal(body).toString();  
  19.         }catch(Exception e){  
  20.             calrResult = "错误的表达式:" + e.getMessage();  
  21.         }  
  22.         ctx.write(Unpooled.copiedBuffer(calrResult.getBytes()));  
  23.     }  
  24.     @Override  
  25.     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
  26.         ctx.flush();  
  27.     }  
  28.     /** 
  29.      * 异常处理 
  30.      */  
  31.     @Override  
  32.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
  33.         cause.printStackTrace();  
  34.         ctx.close();  
  35.     }  
  36. }  

2、客户端

    Client:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.bootstrap.Bootstrap;  
  3. import io.netty.channel.ChannelFuture;  
  4. import io.netty.channel.ChannelInitializer;  
  5. import io.netty.channel.ChannelOption;  
  6. import io.netty.channel.EventLoopGroup;  
  7. import io.netty.channel.nio.NioEventLoopGroup;  
  8. import io.netty.channel.socket.SocketChannel;  
  9. import io.netty.channel.socket.nio.NioSocketChannel;  
  10. import java.util.Scanner;  
  11. public class Client implements Runnable{  
  12.     static ClientHandler client = new ClientHandler();  
  13.     public static void main(String[] args) throws Exception {  
  14.         new Thread(new Client()).start();  
  15.         @SuppressWarnings("resource")  
  16.         Scanner scanner = new Scanner(System.in);  
  17.         while(client.sendMsg(scanner.nextLine()));  
  18.     }  
  19.     @Override  
  20.     public void run() {  
  21.         String host = "127.0.0.1";  
  22.         int port = 9090;  
  23.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  24.         try {  
  25.             Bootstrap b = new Bootstrap();  
  26.             b.group(workerGroup);  
  27.             b.channel(NioSocketChannel.class);  
  28.             b.option(ChannelOption.SO_KEEPALIVE, true);  
  29.             b.handler(new ChannelInitializer<SocketChannel>() {  
  30.                 @Override  
  31.                 public void initChannel(SocketChannel ch) throws Exception {  
  32.                     ch.pipeline().addLast(client);  
  33.                 }  
  34.             });  
  35.             ChannelFuture f = b.connect(host, port).sync();  
  36.             f.channel().closeFuture().sync();  
  37.         } catch (InterruptedException e) {  
  38.             e.printStackTrace();  
  39.         } finally {  
  40.             workerGroup.shutdownGracefully();  
  41.         }  
  42.     }  
  43. }  

    ClientHandler:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.buffer.ByteBuf;  
  3. import io.netty.buffer.Unpooled;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. import java.io.UnsupportedEncodingException;  
  7. public class ClientHandler extends ChannelInboundHandlerAdapter {  
  8.     ChannelHandlerContext ctx;  
  9.     /** 
  10.      * tcp链路简历成功后调用 
  11.      */  
  12.     @Override  
  13.     public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  14.         this.ctx = ctx;  
  15.     }  
  16.     public boolean sendMsg(String msg){  
  17.         System.out.println("客户端发送消息:"+msg);  
  18.         byte[] req = msg.getBytes();  
  19.         ByteBuf m = Unpooled.buffer(req.length);  
  20.         m.writeBytes(req);  
  21.         ctx.writeAndFlush(m);  
  22.         return msg.equals("q")?false:true;  
  23.     }  
  24.     /** 
  25.      * 收到服务器消息后调用 
  26.      * @throws UnsupportedEncodingException  
  27.      */  
  28.     @Override  
  29.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {  
  30.         ByteBuf buf = (ByteBuf) msg;  
  31.         byte[] req = new byte[buf.readableBytes()];  
  32.         buf.readBytes(req);  
  33.         String body = new String(req,"utf-8");  
  34.         System.out.println("服务器消息:"+body);  
  35.     }  
  36.     /** 
  37.      * 发生异常时调用 
  38.      */  
  39.     @Override  
  40.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
  41.         cause.printStackTrace();  
  42.         ctx.close();  
  43.     }  
  44. }  

3、用于计算的工具类


        
        
  1. package com.anxpp.io.utils;
  2. import javax.script.ScriptEngine;
  3. import javax.script.ScriptEngineManager;
  4. import javax.script.ScriptException;
  5. public enum Calculator {
  6. Instance;
  7. private final static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
  8. public Object cal(String expression) throws ScriptException{
  9. return jse.eval(expression);
  10. }
  11. }

4、测试

    分别启动服务端和客户端,然后再客户端控制台输入表达式:

       
       
  1. 1+5+5+5+5+5
  2. 客户端发送消息:1+5+5+5+5+5
  3. 服务器消息:26
  4. 156158*458918+125615
  5. 客户端发送消息:156158*458918+125615
  6. 服务器消息:7.1663842659E10
  7. 1895612+555+5+5+5+5+5+5+5-5*4/4
  8. 客户端发送消息:1895612+555+5+5+5+5+5+5+5-5*4/4
  9. 服务器消息:1896197

    可以看到服务端返回的结果。

    查看服务端控制台:

       
       
  1. 服务器开启:9090
  2. 收到客户端消息:1+5+5+5+5+5
  3. 收到客户端消息:156158*458918+125615
  4. 收到客户端消息:1895612+555+5+5+5+5+5+5+5-5*4/4

5、更多

    相关文章:

    Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

    本文例子以及Java BIO NIO AIO例子的源码Git地址:https://github.com/anxpp/Java-IO.git

    后续会继续更新Netty相关内容,直到一个简陋的通讯服务器完成。

2
 
0
 
 
查看评论
2楼  Ray_Sir_Java2017-08-04 16:57发表 [回复]
AIO的设计思路是非常棒的,但是在LINUX的底层实现有缺陷吧?
1楼  冯尧2017-05-01 20:22发表 [回复]
总结的很详细,谢谢博主分享。
Re:  anxpp2017-05-05 13:09发表 [回复]
回复冯尧:客气
发表评论
  • 用 户 名:
  • thgold
  • 评论内容:
  • 插入代码
  •   
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
  • 个人资料
  •  
    anxpp
     
    3  1
    • 访问:603226次
    • 积分:4832
    • 等级: 
    • 排名:第6269名
    • 原创:95篇
    • 转载:1篇
    • 译文:0篇
    • 评论:236条
  • 博客动向
  • 不久的不久的一段时间后

    本博客将开一个Oracle的专栏

    会更新一批Oracle教程

    Docker技术教程

    Spring Boot相关教程

    anxpp的博客


  • 博客专栏
  • 其他信息

 

Java NIO框架Netty简单使用

  3866人阅读  评论(3)  收藏  举报
  分类:

转载请注明出处:http://blog.csdn.net/anxpp/article/details/52108238,谢谢!

    之前写了一篇文章:Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码),介绍了如何使用Java原生IO支持进行网络编程,本文介绍一种更为简单的方式,即Java NIO框架。

    Netty是业界最流行的NIO框架之一,具有良好的健壮性、功能、性能、可定制性和可扩展性。同时,它提供的十分简单的API,大大简化了我们的网络编程。

    同Java IO介绍的文章一样,本文所展示的例子,实现了一个相同的功能。

1、服务端

    Server:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.bootstrap.ServerBootstrap;  
  3. import io.netty.channel.ChannelFuture;  
  4. import io.netty.channel.ChannelInitializer;  
  5. import io.netty.channel.ChannelOption;  
  6. import io.netty.channel.EventLoopGroup;  
  7. import io.netty.channel.nio.NioEventLoopGroup;  
  8. import io.netty.channel.socket.SocketChannel;  
  9. import io.netty.channel.socket.nio.NioServerSocketChannel;  
  10. public class Server {  
  11.     private int port;  
  12.     public Server(int port) {  
  13.         this.port = port;  
  14.     }  
  15.     public void run() throws Exception {  
  16.         EventLoopGroup bossGroup = new NioEventLoopGroup();  
  17.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  18.         try {  
  19.             ServerBootstrap b = new ServerBootstrap();  
  20.             b.group(bossGroup, workerGroup)  
  21.              .channel(NioServerSocketChannel.class)  
  22.              .option(ChannelOption.SO_BACKLOG, 1024)  
  23.              .childOption(ChannelOption.SO_KEEPALIVE, true)  
  24.              .childHandler(new ChannelInitializer<SocketChannel>() {  
  25.                  @Override  
  26.                  public void initChannel(SocketChannel ch) throws Exception {  
  27.                      ch.pipeline().addLast(new ServerHandler());  
  28.                  }  
  29.              });  
  30.             ChannelFuture f = b.bind(port).sync();  
  31.             System.out.println("服务器开启:"+port);  
  32.             f.channel().closeFuture().sync();  
  33.         } finally {  
  34.             workerGroup.shutdownGracefully();  
  35.             bossGroup.shutdownGracefully();  
  36.         }  
  37.     }  
  38.     public static void main(String[] args) throws Exception {  
  39.         int port;  
  40.         if (args.length > 0) {  
  41.             port = Integer.parseInt(args[0]);  
  42.         } else {  
  43.             port = 9090;  
  44.         }  
  45.         new Server(port).run();  
  46.     }  
  47. }  

    ServerHandler:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.buffer.ByteBuf;  
  3. import io.netty.buffer.Unpooled;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. import java.io.UnsupportedEncodingException;  
  7. import com.anxpp.io.utils.Calculator;  
  8. public class ServerHandler extends ChannelInboundHandlerAdapter {  
  9.     @Override  
  10.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {  
  11.         ByteBuf in = (ByteBuf) msg;  
  12.         byte[] req = new byte[in.readableBytes()];  
  13.         in.readBytes(req);  
  14.         String body = new String(req,"utf-8");  
  15.         System.out.println("收到客户端消息:"+body);  
  16.         String calrResult = null;  
  17.         try{  
  18.             calrResult = Calculator.Instance.cal(body).toString();  
  19.         }catch(Exception e){  
  20.             calrResult = "错误的表达式:" + e.getMessage();  
  21.         }  
  22.         ctx.write(Unpooled.copiedBuffer(calrResult.getBytes()));  
  23.     }  
  24.     @Override  
  25.     public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {  
  26.         ctx.flush();  
  27.     }  
  28.     /** 
  29.      * 异常处理 
  30.      */  
  31.     @Override  
  32.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
  33.         cause.printStackTrace();  
  34.         ctx.close();  
  35.     }  
  36. }  

2、客户端

    Client:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.bootstrap.Bootstrap;  
  3. import io.netty.channel.ChannelFuture;  
  4. import io.netty.channel.ChannelInitializer;  
  5. import io.netty.channel.ChannelOption;  
  6. import io.netty.channel.EventLoopGroup;  
  7. import io.netty.channel.nio.NioEventLoopGroup;  
  8. import io.netty.channel.socket.SocketChannel;  
  9. import io.netty.channel.socket.nio.NioSocketChannel;  
  10. import java.util.Scanner;  
  11. public class Client implements Runnable{  
  12.     static ClientHandler client = new ClientHandler();  
  13.     public static void main(String[] args) throws Exception {  
  14.         new Thread(new Client()).start();  
  15.         @SuppressWarnings("resource")  
  16.         Scanner scanner = new Scanner(System.in);  
  17.         while(client.sendMsg(scanner.nextLine()));  
  18.     }  
  19.     @Override  
  20.     public void run() {  
  21.         String host = "127.0.0.1";  
  22.         int port = 9090;  
  23.         EventLoopGroup workerGroup = new NioEventLoopGroup();  
  24.         try {  
  25.             Bootstrap b = new Bootstrap();  
  26.             b.group(workerGroup);  
  27.             b.channel(NioSocketChannel.class);  
  28.             b.option(ChannelOption.SO_KEEPALIVE, true);  
  29.             b.handler(new ChannelInitializer<SocketChannel>() {  
  30.                 @Override  
  31.                 public void initChannel(SocketChannel ch) throws Exception {  
  32.                     ch.pipeline().addLast(client);  
  33.                 }  
  34.             });  
  35.             ChannelFuture f = b.connect(host, port).sync();  
  36.             f.channel().closeFuture().sync();  
  37.         } catch (InterruptedException e) {  
  38.             e.printStackTrace();  
  39.         } finally {  
  40.             workerGroup.shutdownGracefully();  
  41.         }  
  42.     }  
  43. }  

    ClientHandler:

[java]  view plain  copy
 print ?
  1. package com.anxpp.io.calculator.netty;  
  2. import io.netty.buffer.ByteBuf;  
  3. import io.netty.buffer.Unpooled;  
  4. import io.netty.channel.ChannelHandlerContext;  
  5. import io.netty.channel.ChannelInboundHandlerAdapter;  
  6. import java.io.UnsupportedEncodingException;  
  7. public class ClientHandler extends ChannelInboundHandlerAdapter {  
  8.     ChannelHandlerContext ctx;  
  9.     /** 
  10.      * tcp链路简历成功后调用 
  11.      */  
  12.     @Override  
  13.     public void channelActive(ChannelHandlerContext ctx) throws Exception {  
  14.         this.ctx = ctx;  
  15.     }  
  16.     public boolean sendMsg(String msg){  
  17.         System.out.println("客户端发送消息:"+msg);  
  18.         byte[] req = msg.getBytes();  
  19.         ByteBuf m = Unpooled.buffer(req.length);  
  20.         m.writeBytes(req);  
  21.         ctx.writeAndFlush(m);  
  22.         return msg.equals("q")?false:true;  
  23.     }  
  24.     /** 
  25.      * 收到服务器消息后调用 
  26.      * @throws UnsupportedEncodingException  
  27.      */  
  28.     @Override  
  29.     public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {  
  30.         ByteBuf buf = (ByteBuf) msg;  
  31.         byte[] req = new byte[buf.readableBytes()];  
  32.         buf.readBytes(req);  
  33.         String body = new String(req,"utf-8");  
  34.         System.out.println("服务器消息:"+body);  
  35.     }  
  36.     /** 
  37.      * 发生异常时调用 
  38.      */  
  39.     @Override  
  40.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
  41.         cause.printStackTrace();  
  42.         ctx.close();  
  43.     }  
  44. }  

3、用于计算的工具类


         
         
  1. package com.anxpp.io.utils;
  2. import javax.script.ScriptEngine;
  3. import javax.script.ScriptEngineManager;
  4. import javax.script.ScriptException;
  5. public enum Calculator {
  6. Instance;
  7. private final static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
  8. public Object cal(String expression) throws ScriptException{
  9. return jse.eval(expression);
  10. }
  11. }

4、测试

    分别启动服务端和客户端,然后再客户端控制台输入表达式:

        
        
  1. 1+5+5+5+5+5
  2. 客户端发送消息:1+5+5+5+5+5
  3. 服务器消息:26
  4. 156158*458918+125615
  5. 客户端发送消息:156158*458918+125615
  6. 服务器消息:7.1663842659E10
  7. 1895612+555+5+5+5+5+5+5+5-5*4/4
  8. 客户端发送消息:1895612+555+5+5+5+5+5+5+5-5*4/4
  9. 服务器消息:1896197

    可以看到服务端返回的结果。

    查看服务端控制台:

        
        
  1. 服务器开启:9090
  2. 收到客户端消息:1+5+5+5+5+5
  3. 收到客户端消息:156158*458918+125615
  4. 收到客户端消息:1895612+555+5+5+5+5+5+5+5-5*4/4

5、更多

    相关文章:

    Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

    本文例子以及Java BIO NIO AIO例子的源码Git地址:https://github.com/anxpp/Java-IO.git

    后续会继续更新Netty相关内容,直到一个简陋的通讯服务器完成。

2
 
0
 
 
width="960" frameborder="0" height="90" scrolling="no" src="http://pos.baidu.com/s?hei=90&wid=960&di=u2998112&ltu=http%3A%2F%2Fblog.csdn.net%2Fanxpp%2Farticle%2Fdetails%2F52108238&cfv=0&pss=1369x9054&ari=2&par=1536x824&cec=UTF-8&cja=false&pcs=1369x674&ps=8909x336&exps=111000&tcn=1507689261&cce=true&psr=1536x864&ant=0&cdo=-1&drs=1&dis=0&chi=1&cpl=4&ltr=http%3A%2F%2Fblog.csdn.net%2Fanxpp%2Farticle%2Fdetails%2F51512200&cmi=5&pis=-1x-1&dc=2&tlm=1507689261&dri=1&dtm=HTML_POST&dai=2&tpr=1507689261288&col=zh-CN&ccd=24&ti=Java%20NIO%E6%A1%86%E6%9E%B6Netty%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8%20-%20anxpp%E7%9A%84%E5%8D%9A%E5%AE%A2%20-%20CSDN%E5%8D%9A%E5%AE%A2">
查看评论
2楼  Ray_Sir_Java2017-08-04 16:57发表 [回复]
AIO的设计思路是非常棒的,但是在LINUX的底层实现有缺陷吧?
1楼  冯尧2017-05-01 20:22发表 [回复]
总结的很详细,谢谢博主分享。
Re:  anxpp2017-05-05 13:09发表 [回复]
回复冯尧:客气
发表评论
  • 用 户 名:
  • thgold
  • 评论内容:
  • 插入代码
  •   
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
  • 个人资料
  •  
    anxpp
     
    3  1
    • 访问:603226次
    • 积分:4832
    • 等级: 
    • 排名:第6269名
    • 原创:95篇
    • 转载:1篇
    • 译文:0篇
    • 评论:236条
  • 博客动向
  • 不久的不久的一段时间后

    本博客将开一个Oracle的专栏

    会更新一批Oracle教程

    Docker技术教程

    Spring Boot相关教程

    anxpp的博客


  • 博客专栏
  • 其他信息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值