1、Netty简介
Netty是由JBOSS提供的一个java开源网络通讯框架。Netty是基于Java NIO client-server的网络应用框架,使用Netty可以快速开发网络应用,例如服务器和客户端协议。Netty提供了一种新的方式来开发网络应用程序,这种新的方式使它很容易使用和具有很强的扩展性。Netty的内部实现是很复杂的,但是Netty提供了简单易用的API从网络处理代码中解耦业务逻辑。Netty是完全基于NIO实现的,所以整个Netty都是异步的。
netty的优点
它的健壮性、功能、性能、可定制性和可扩展性在同类框架都是首屈一指的。它已经得到成百上千的商业/商用项目验证,如Hadoop的RPC框架Avro、RocketMQ以及主流的分布式通信框架Dubbox等等。
2、Hello World 入门
1、Netty通信的步骤:
①创建两个NIO线程组,一个专门用于网络事件处理(接受客户端的连接),另一个则进行网络通信的读写。
②创建一个ServerBootstrap对象,配置Netty的一系列参数,例如接受传出数据的缓存大小等。
③创建一个用于实际处理数据的类ChannelInitializer,进行初始化的准备工作,比如设置接受传出数据的字符集、格式以及实际处理数据的接口。
④绑定端口,执行同步阻塞方法等待服务器端启动即可。
2、入门实例(以helloworld为例)
2.1下载相应的jar包
可以去http://netty.io/上下载所需的Netty包
我所用的jar包为 https://pan.baidu.com/s/1tm2EgYtDpTS5dejVnHhvPw 密码:vc8b
2.2 代码实现
服务器端
package com.xyq.netty.hello; 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 { public static void main(String[] args) throws Exception { //1 创建两个线程组 EventLoopGroup pGroup = new NioEventLoopGroup();//一个是用于处理服务器端接收客户端连接的 EventLoopGroup cGroup = new NioEventLoopGroup();//一个是进行网络通信的(网络读写的) //2 创建辅助工具类,用于服务器通道的一系列配置 ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(pGroup, cGroup)//绑定俩个线程组 .channel(NioServerSocketChannel.class)//指定NIO的模式 .option(ChannelOption.SO_BACKLOG, 1024)//设置tcp缓冲区 .option(ChannelOption.SO_SNDBUF, 32*1024)//设置发送缓冲大小 .option(ChannelOption.SO_RCVBUF, 32*1024)//设置接收缓冲大小 .option(ChannelOption.SO_KEEPALIVE, true)//保持连接 .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { //3 在这里配置具体数据接收方法的处理 ch.pipeline().addLast(new ServerHandler()); } }); //4 进行绑定 ChannelFuture cf = bootstrap.bind(8765).sync(); System.out.println("server start ..."); //5 等待关闭 cf.channel().closeFuture().sync(); pGroup.shutdownGracefully(); cGroup.shutdownGracefully(); } }
服务器管理类
package com.xyq.netty.hello; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; public class ServerHandler extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //读取客户端发过来的信息 ByteBuf buf = (ByteBuf) msg; byte[] bs = new byte[buf.readableBytes()]; buf.readBytes(bs); String body = new String(bs, "utf-8"); System.out.println("server 接收到的数据为 " + body); //给客户端回应信息 String result = "server 已经接收到信息, 信息为 " + body; ctx.writeAndFlush(Unpooled.copiedBuffer(result.getBytes())); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
客户端
package com.xyq.netty.hello; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; public class Client { public static void main(String[] args)throws Exception { //1 创建线程组 EventLoopGroup group = new NioEventLoopGroup(); //2 创建辅助工具类,用于服务器通道的一系列配置 Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group)//绑定线程组 .channel(NioSocketChannel.class)//指定NIO的模式 .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { //3 在这里配置具体数据接收方法的处理 ch.pipeline().addLast(new ClientHandler()); } }); //4 进行连接 ChannelFuture future = bootstrap.connect("127.0.0.1", 8765).sync(); System.out.println("Client connect...."); //5发送信息 future.channel().writeAndFlush(Unpooled.copiedBuffer("你好".getBytes())); Thread.sleep(1000); future.channel().writeAndFlush(Unpooled.copiedBuffer("世界".getBytes())); Thread.sleep(1000); future.channel().writeAndFlush(Unpooled.copiedBuffer("!".getBytes())); //6等待关闭 future.channel().closeFuture().sync(); group.shutdownGracefully(); } }
客户端管理类
package com.xyq.netty.hello; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerContext; import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { try { //读取服务器端发过来的信息 ByteBuf buf = (ByteBuf) msg; byte[] bs = new byte[buf.readableBytes()]; buf.readBytes(bs); String body = new String(bs, "utf-8"); System.out.println("客户端接收到服务端的响应消息 " + body); } finally{ ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }