一. 介绍
提供异步的,事件驱动的网络应用程序框架和工具,用以快速开发高性能,高可靠性的网络服务器和客户端程序;
特性(百度)
- 设计
统一的API,适用于不同的协议(阻塞和非阻塞)
基于灵活.可扩展的事件驱动模型
高度可定制的线程模型
可靠的无连接数据Socket支持(UDP) - 性能
更好的吞吐量,低延迟
更深资源
尽量减少不必要的内存拷贝 - 安全
完整的ssl/TLS和SRARTTLS的支持 - 易用
完善的java doc
二.Netty主要组件
Channel -----对应Nio中的channel
EventLoop ------- 对应Nio中的while循环
EventLoopGroup-----多个EventLoop
ChannelHandler 和ChannelPipeline-----对用Nio中的客户逻辑实现handleRead/handleWrite(责任链(拦截器)模式 )
ByteBuf ------ 对应NIO中的BytBuffer
Bootstrap 和 ServerBootstrap -----对应NIO中的Selector,ServerSocketChannel等的创建,配置,启动等
三.简单使用
- maven 依赖
io.netty
netty-all
4.1.30.Final
- server端代码:
/**
* @ClassName NettyServer
* @Description TODO
* @Author liuzetian
* @Date 2019/5/6 8:54 AM
* @Version 1.0
**/
public class NettyServer {
public static void main(String[] args) {
int port = 8080;
new NettyServer().startServer(port);
}
public void startServer(int port) {
//第一步
//配置服务端的NIO线程组
//祝线程组 用于接受客户端的联机额,但是不做任何具体业务处理,like boss,负责接待客户 不具体服务客户
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
// 具体工作线程组 boss线程组会把任务丢给他,让手下线程组去做任务 服务客户
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workGroup)
//配置server 通道
.channel(NioServerSocketChannel.class)
//配置通道的ChannelPipeline
.childHandler(new ChildChannelHandler());
//绑定端口 并启动server 同时设置启动方式为同步
ChannelFuture future = bootstrap.bind(port).sync();
System.out.println(NettyServer.class.getName() + "启动成功,在地址["+ future.channel().localAddress() + "]上等待客户请求......");
//等待服务端监听端口关闭
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyServerHandler());
}
}
}
ChannelHandler
/**
* @ClassName Netty
* @Description TODO
* @Author liuzetian
* @Date 2019/5/6 9:02 AM
* @Version 1.0
**/
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println( "服务器接收到消息:" + in.toString(CharsetUtil.UTF_8));
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
.addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
- client端代码
/**
* @ClassName NettyClient
* @Description TODO
* @Author liuzetian
* @Date 2019/5/6 9:18 AM
* @Version 1.0
**/
public class NettyClient {
public static void main(String[] args) throws Exception {
int port = 8080;
new NettyClient().connect(port, "127.0.0.1");
}
public void connect(int port, String host) throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new NettyClientHandler());
}
});
// 发起异步连接操作
ChannelFuture future = bootstrap.connect(host, port).sync();
// 等待客户端链路关闭
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
}
/**
* @ClassName NettyClientHandler
* @Description TODO
* @Author liuzetian
* @Date 2019/5/6 9:22 AM
* @Version 1.0
**/
public class NettyClientHandler extends SimpleChannelInboundHandler {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
System.out.println("客户端收到消息:" + byteBuf.toString(CharsetUtil.UTF_8));
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello World!\n", CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
运行
client端:
server端:
代码比较简单,如有错误,欢迎指正;