欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-18 09:28:52
之前写了一篇文章:java 网络io编程总结(bio、nio、aio均含完整实例代码),介绍了如何使用java原生io支持进行网络编程,本文介绍一种更为简单的方式,即jav...

之前写了一篇文章: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相关内容,直到一个简陋的通讯服务器完成。

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

上一篇:

下一篇: