Netty学习:搭建一个简单的Netty服务
Netty学习:搭建一个简单的Netty服务
Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。Netty 已逐渐成为 Java NIO 编程的首选框架。
项目官方地址:http://netty.io/index.html
一. Netty 的优点:
- API 使用简单,开发门槛低;
- 功能强大,预置了多种编解码功能,支持多种主流协议;
- 定制能力强,可以通过 ChannelHandler 对通信框架进行灵活的扩展;
- 性能高,通过与其它业界主流的 NIO 框架对比,Netty 的综合性能最优;
- 社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会被加入;
- 经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它完全满足不同行业的商用标准。
二. 搭建Netty服务:
- 添加pom依赖
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.0.Final</version> </dependency>
- SimpleServer(服务端)
package com.yingjun.netty.server; 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; /** * * Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输, * 例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。 * */ public class SimpleServer { private int port; public SimpleServer(int port) { this.port = port; } public void run() throws Exception { //EventLoopGroup是用来处理IO操作的多线程事件循环器 //bossGroup 用来接收进来的连接 EventLoopGroup bossGroup = new NioEventLoopGroup(); //workerGroup 用来处理已经被接收的连接 EventLoopGroup workerGroup = new NioEventLoopGroup(); try { //启动 NIO 服务的辅助启动类 ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) //配置 Channel .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { // 注册handler ch.pipeline().addLast(new SimpleServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); // 绑定端口,开始接收进来的连接 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 。 f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { new SimpleServer(9999).run(); } }
- SimpleServerHandler(服务端请求处理Handler)
package com.yingjun.netty.server; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class SimpleServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("SimpleServerHandler.channelRead"); ByteBuf result = (ByteBuf) msg; byte[] result1 = new byte[result.readableBytes()]; // msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中 result.readBytes(result1); String resultStr = new String(result1); // 接收并打印客户端的信息 System.out.println("Client said:" + resultStr); // 释放资源,这行很关键 result.release(); // 向客户端发送消息 String response = "hello client!"; // 在当前场景下,发送的数据必须转换成ByteBuf数组 ByteBuf encoded = ctx.alloc().buffer(4 * response.length()); encoded.writeBytes(response.getBytes()); ctx.write(encoded); ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 当出现异常就关闭连接 cause.printStackTrace(); ctx.close(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } }
- SimpleServer(客户端)
package com.yingjun.netty.server; import io.netty.bootstrap.Bootstrap; 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; import io.netty.channel.socket.nio.NioSocketChannel; public class SimpleClient { public void connect(String host, int port) throws Exception { 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(new SimpleClientHandler()); } }); // Start the client. ChannelFuture f = b.connect(host, port).sync(); // Wait until the connection is closed. f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { SimpleClient client=new SimpleClient(); client.connect("127.0.0.1", 9999); } }
- SimpleServerHandler(客户端请求处理Handler)
package com.yingjun.netty.server; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class SimpleClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { System.out.println("SimpleClientHandler.channelRead"); ByteBuf result = (ByteBuf) msg; byte[] result1 = new byte[result.readableBytes()]; result.readBytes(result1); System.out.println("Server said:" + new String(result1)); result.release(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 当出现异常就关闭连接 cause.printStackTrace(); ctx.close(); } // 连接成功后,向server发送消息 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String msg = "hello Server!"; ByteBuf encoded = ctx.alloc().buffer(4 * msg.length()); encoded.writeBytes(msg.getBytes()); ctx.write(encoded); ctx.flush(); } }
- 运行结果:
SimpleClientHandler.channelRead Server said:hello client! ------------------------------------------ SimpleServerHandler.channelRead Client said:hello Server! SimpleServerHandler.channelRead Client said:hello Server!
相关推荐
fengshantao 2020-10-29
arctan0 2020-10-14
爱传文档 2020-07-28
gzx0 2020-07-05
fengshantao 2020-07-04
fengshantao 2020-07-02
jannal 2020-06-21
arctan0 2020-06-19
arctan0 2020-06-16
gzx0 2020-06-14
fengshantao 2020-06-13
gzx0 2020-06-12
arctan0 2020-06-11
fengshantao 2020-06-11
mbcsdn 2020-05-19
arctan0 2020-05-16
爱传文档 2020-05-08
爱传文档 2020-05-04