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();
}
}