Java NIO框架Netty简单使用的示例

 更新时间:2017年12月29日 13:43:57   作者:anxpp  
本篇文章主要介绍了Java NIO框架Netty简单使用的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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

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

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

1、服务端

Server:

package com.anxpp.io.calculator.netty; 
import io.netty.bootstrap.ServerBootstrap; 
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; 
public class Server { 
  private int port; 
  public Server(int port) { 
    this.port = port; 
  } 
  public void run() throws Exception { 
    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 
    try { 
      ServerBootstrap b = new ServerBootstrap(); 
      b.group(bossGroup, workerGroup) 
       .channel(NioServerSocketChannel.class) 
       .option(ChannelOption.SO_BACKLOG, 1024) 
       .childOption(ChannelOption.SO_KEEPALIVE, true) 
       .childHandler(new ChannelInitializer<SocketChannel>() { 
         @Override 
         public void initChannel(SocketChannel ch) throws Exception { 
           ch.pipeline().addLast(new ServerHandler()); 
         } 
       }); 
      ChannelFuture f = b.bind(port).sync(); 
      System.out.println("服务器开启:"+port); 
      f.channel().closeFuture().sync(); 
    } finally { 
      workerGroup.shutdownGracefully(); 
      bossGroup.shutdownGracefully(); 
    } 
  } 
  public static void main(String[] args) throws Exception { 
    int port; 
    if (args.length > 0) { 
      port = Integer.parseInt(args[0]); 
    } else { 
      port = 9090; 
    } 
    new Server(port).run(); 
  } 
} 

ServerHandler:

package com.anxpp.io.calculator.netty; 
import io.netty.buffer.ByteBuf; 
import io.netty.buffer.Unpooled; 
import io.netty.channel.ChannelHandlerContext; 
import io.netty.channel.ChannelInboundHandlerAdapter; 
import java.io.UnsupportedEncodingException; 
import com.anxpp.io.utils.Calculator; 
public class ServerHandler extends ChannelInboundHandlerAdapter { 
  @Override 
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException { 
    ByteBuf in = (ByteBuf) msg; 
    byte[] req = new byte[in.readableBytes()]; 
    in.readBytes(req); 
    String body = new String(req,"utf-8"); 
    System.out.println("收到客户端消息:"+body); 
    String calrResult = null; 
    try{ 
      calrResult = Calculator.Instance.cal(body).toString(); 
    }catch(Exception e){ 
      calrResult = "错误的表达式:" + e.getMessage(); 
    } 
    ctx.write(Unpooled.copiedBuffer(calrResult.getBytes())); 
  } 
  @Override 
  public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
    ctx.flush(); 
  } 
  /** 
   * 异常处理 
   */ 
  @Override 
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    cause.printStackTrace(); 
    ctx.close(); 
  } 
} 
package com.anxpp.io.calculator.netty; 
import io.netty.buffer.ByteBuf; 
import io.netty.buffer.Unpooled; 
import io.netty.channel.ChannelHandlerContext; 
import io.netty.channel.ChannelInboundHandlerAdapter; 
import java.io.UnsupportedEncodingException; 
import com.anxpp.io.utils.Calculator; 
public class ServerHandler extends ChannelInboundHandlerAdapter { 
  @Override 
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException { 
    ByteBuf in = (ByteBuf) msg; 
    byte[] req = new byte[in.readableBytes()]; 
    in.readBytes(req); 
    String body = new String(req,"utf-8"); 
    System.out.println("收到客户端消息:"+body); 
    String calrResult = null; 
    try{ 
      calrResult = Calculator.Instance.cal(body).toString(); 
    }catch(Exception e){ 
      calrResult = "错误的表达式:" + e.getMessage(); 
    } 
    ctx.write(Unpooled.copiedBuffer(calrResult.getBytes())); 
  } 
  @Override 
  public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { 
    ctx.flush(); 
  } 
  /** 
   * 异常处理 
   */ 
  @Override 
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    cause.printStackTrace(); 
    ctx.close(); 
  } 
} 

2、客户端

Client:

package com.anxpp.io.calculator.netty; 
import io.netty.bootstrap.Bootstrap; 
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 java.util.Scanner; 
public class Client implements Runnable{ 
  static ClientHandler client = new ClientHandler(); 
  public static void main(String[] args) throws Exception { 
    new Thread(new Client()).start(); 
    @SuppressWarnings("resource") 
    Scanner scanner = new Scanner(System.in); 
    while(client.sendMsg(scanner.nextLine())); 
  } 
  @Override 
  public void run() { 
    String host = "127.0.0.1"; 
    int port = 9090; 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 
    try { 
      Bootstrap b = new Bootstrap(); 
      b.group(workerGroup); 
      b.channel(NioSocketChannel.class); 
      b.option(ChannelOption.SO_KEEPALIVE, true); 
      b.handler(new ChannelInitializer<SocketChannel>() { 
        @Override 
        public void initChannel(SocketChannel ch) throws Exception { 
          ch.pipeline().addLast(client); 
        } 
      }); 
      ChannelFuture f = b.connect(host, port).sync(); 
      f.channel().closeFuture().sync(); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } finally { 
      workerGroup.shutdownGracefully(); 
    } 
  } 
} 

ClientHandler:

package com.anxpp.io.calculator.netty; 
import io.netty.buffer.ByteBuf; 
import io.netty.buffer.Unpooled; 
import io.netty.channel.ChannelHandlerContext; 
import io.netty.channel.ChannelInboundHandlerAdapter; 
import java.io.UnsupportedEncodingException; 
public class ClientHandler extends ChannelInboundHandlerAdapter { 
  ChannelHandlerContext ctx; 
  /** 
   * tcp链路简历成功后调用 
   */ 
  @Override 
  public void channelActive(ChannelHandlerContext ctx) throws Exception { 
    this.ctx = ctx; 
  } 
  public boolean sendMsg(String msg){ 
    System.out.println("客户端发送消息:"+msg); 
    byte[] req = msg.getBytes(); 
    ByteBuf m = Unpooled.buffer(req.length); 
    m.writeBytes(req); 
    ctx.writeAndFlush(m); 
    return msg.equals("q")?false:true; 
  } 
  /** 
   * 收到服务器消息后调用 
   * @throws UnsupportedEncodingException 
   */ 
  @Override 
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException { 
    ByteBuf buf = (ByteBuf) msg; 
    byte[] req = new byte[buf.readableBytes()]; 
    buf.readBytes(req); 
    String body = new String(req,"utf-8"); 
    System.out.println("服务器消息:"+body); 
  } 
  /** 
   * 发生异常时调用 
   */ 
  @Override 
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
    cause.printStackTrace(); 
    ctx.close(); 
  } 
} 

3、用于计算的工具类

package com.anxpp.io.utils;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public enum Calculator {
  Instance;
  private final static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
  public Object cal(String expression) throws ScriptException{
    return jse.eval(expression);
  }
}

4、测试

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

1+5+5+5+5+5
客户端发送消息:1+5+5+5+5+5
服务器消息:26
156158*458918+125615
客户端发送消息:156158*458918+125615
服务器消息:7.1663842659E10
1895612+555+5+5+5+5+5+5+5-5*4/4
客户端发送消息:1895612+555+5+5+5+5+5+5+5-5*4/4
服务器消息:1896197

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

查看服务端控制台:

服务器开启:9090
收到客户端消息:1+5+5+5+5+5
收到客户端消息:156158*458918+125615
收到客户端消息: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相关内容,直到一个简陋的通讯服务器完成。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • RestTemplate文件上传下载与大文件流式下载

    RestTemplate文件上传下载与大文件流式下载

    这篇文章主要为大家介绍了RestTemplate文件上传下载与大文件流式下载的使用方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步
    2022-03-03
  • BaseMapper接口的使用方法

    BaseMapper接口的使用方法

    这篇文章主要介绍了BaseMapper接口的使用方法,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-12-12
  • Java中出现java.lang.IllegalStateException异常错误的解决

    Java中出现java.lang.IllegalStateException异常错误的解决

    这篇文章主要介绍了Java中出现java.lang.IllegalStateException异常错误的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Java异常 Factory method''sqlSessionFactory''rew exception;ested exception is java.lang.NoSuchMethodError:

    Java异常 Factory method''sqlSessionFactory''rew exception;este

    这篇文章主要介绍了Java异常 Factory method ‘sqlSessionFactory‘ threw exception; nested exception is java.lang.NoSuchMethodError:,本文介绍了springboot 引入mybatis-plus后报错的解决方案,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • Java gbk转utf-8

    Java gbk转utf-8

    本文主要介绍了Java gbk转utf-8的方法,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • java二维码生成的方法

    java二维码生成的方法

    这篇文章主要为大家详细介绍了java二维码生成的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Java Online Exam在线考试系统的实现

    Java Online Exam在线考试系统的实现

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用java+springboot+vue+jsp+mysql+maven实现Online Exam在线考试系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • Java连接Vmware中的redis

    Java连接Vmware中的redis

    这篇文章主要为大家介绍了Java连接Vmware中的redis
    2016-01-01
  • JAVA查询MongoDB的几种方法小结

    JAVA查询MongoDB的几种方法小结

    本文主要介绍了JAVA查询MongoDB的几种方法小结,通过阅读本文,读者可以了解如何使用Java查询MongoDB,并在实际应用中应用这些技能,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • java实现的DES加密算法详解

    java实现的DES加密算法详解

    这篇文章主要介绍了java实现的DES加密算法,结合实例形式详细分析了java实现DES加密操作的原理、实现技巧与相关注意事项,需要的朋友可以参考下
    2017-06-06

最新评论