Java NIO框架Netty简单使用的示例
作者:anxpp 时间:2022-09-08 02:51:27
之前写了一篇文章: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相关内容,直到一个简陋的通讯服务器完成。
来源:http://blog.csdn.net/anxpp/article/details/52108238
标签:Java,NIO,Netty
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
javaweb 项目初始配置的方法步骤
2021-12-23 17:34:23
![](https://img.aspxhome.com/file/2023/8/63418_0s.jpg)
利用json2POJO with Lombok 插件自动生成java类的操作
2023-07-12 09:31:28
![](https://img.aspxhome.com/file/2023/8/69718_0s.jpg)
Java调用第三方接口示范的实现
2023-06-27 20:32:10
![](https://img.aspxhome.com/file/2023/8/67468_0s.png)
基于Mybatis映射的一点心得(分享)
2023-08-08 13:15:53
SpringBoot 过滤器 Filter使用实例详解
2021-11-08 13:46:00
AJAX中Get请求报错404的原因以及解决办法
2021-07-03 05:41:07
![](https://img.aspxhome.com/file/2023/2/67442_0s.jpg)
Java二叉搜索树基础原理与实现方法详解
2022-09-12 17:20:59
![](https://img.aspxhome.com/file/2023/4/65154_0s.png)
Windows下Java环境变量配置详解
2022-02-04 05:56:02
解决Java提示正在尝试分配更低的访问权限问题
2023-11-04 09:31:08
![](https://img.aspxhome.com/file/2023/9/58539_0s.png)
c#使用listbox的详细方法和常见问题解决
2023-08-27 11:28:56
![](https://img.aspxhome.com/file/2023/9/68069_0s.jpg)
C#对多个集合和数组的操作方法(合并,去重,判断)
2021-12-11 14:02:44
Java拷贝数组方法Arrays.copyOf()是地址传递的证明实例
2023-11-08 11:51:29
![](https://img.aspxhome.com/file/2023/5/58215_0s.png)
Spark调优多线程并行处理任务实现方式
2023-08-21 15:43:53
一文带你了解RabbitMQ消息转换器
2023-11-15 23:22:28
![](https://img.aspxhome.com/file/2023/4/64384_0s.jpg)
在Spring Boot中从类路径加载文件的示例
2023-11-11 21:53:44
C#实现类似新浪微博长URL转短地址的方法
2023-06-02 12:59:28
Springboot启动后执行方法小结
2022-09-26 22:12:02
SpringBoot的@Value给静态变量注入application.properties属性值
2023-09-20 11:54:07
Struts中使用validate()输入校验方法详解
2023-03-02 19:10:41
![](https://img.aspxhome.com/file/2023/4/63744_0s.png)
Spring实战之使用注解实现声明式事务操作示例
2021-08-19 07:16:07