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相关内容,直到一个简陋的通讯服务器完成。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。