Netty学习 HelloWorld

版权声明:本文为博主原创文章,允许转载,请加原文链接。 https://blog.csdn.net/oYueYang1/article/details/80476053

Netty学习 HelloWorld

1.Netty简介

Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便的主动获取或者通过通知机制获得IO操作结果。

作为当前最流行的NIO框架,Netty在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于Netty的NIO框架构建。

2 Netty 核心组件

2.1 Bootstrap 和 ServerBootstrap

Netty 应用程序通过设置 bootstrap(引导)类的开始,该类提供了一个 用于应用程序网络层配置的容器。

2.2Channel

底层网络传输 API 必须提供给应用 I/O操作的接口,如读,写,连接,绑定等等。对于我们来说,这是结构几乎总是会成为一个“socket”。 Netty 中的接口 Channel 定义了与 socket 丰富交互的操作集:bind, close, config, connect, isActive, isOpen, isWritable, read, write 等等。 Netty 提供大量的 Channel 实现来专门使用。这些包括 AbstractChannel,AbstractNioByteChannel,AbstractNioChannel,EmbeddedChannel, LocalServerChannel,NioSocketChannel 等等。

2.3 ChannelHandler

ChannelHandler 支持很多协议,并且提供用于数据处理的容器。我们已经知道 ChannelHandler 由特定事件触发。 ChannelHandler 可专用于几乎所有的动作,包括将一个对象转为字节(或相反),执行过程中抛出的异常处理。

2.4 ChannelPipeline

ChannelPipeline 提供了一个容器给 ChannelHandler 链并提供了一个API 用于管理沿着链入站和出站事件的流动。每个 Channel 都有自己的ChannelPipeline,当 Channel 创建时自动创建的。 ChannelHandler 是如何安装在 ChannelPipeline? 主要是实现了ChannelHandler 的抽象 ChannelInitializer。ChannelInitializer子类 通过 ServerBootstrap 进行注册。当它的方法 initChannel() 被调用时,这个对象将安装自定义的 ChannelHandler 集到 pipeline。当这个操作完成时,ChannelInitializer 子类则 从 ChannelPipeline 自动删除自身。

2.5 EventLoop

EventLoop 用于处理 Channel 的 I/O 操作。一个单一的 EventLoop通常会处理多个 Channel 事件。一个 EventLoopGroup 可以含有多于一个的 EventLoop 和 提供了一种迭代用于检索清单中的下一个。

2.6 ChannelFuture

Netty 所有的 I/O 操作都是异步。因为一个操作可能无法立即返回,我们需要有一种方法在以后确定它的结果。出于这个目的,Netty 提供了接口 ChannelFuture,它的 addListener 方法注册了一个 ChannelFutureListener ,当操作完成时,可以被通知(不管成功与否)。

/**
 * Netty Server
 * Created by lyyz on 2018/5/25.
 */
public class Server {

    public static void main(String[] args) throws InterruptedException {
        //用于处理服务器端接收客户端连接的
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //进行网络通信的(网络读写的)
        EventLoopGroup workGroup = new NioEventLoopGroup();
        //创建辅助工具类,用于服务器通道的一系列配置
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        //绑定俩个线程组
        serverBootstrap.group(bossGroup,workGroup);
        //指定NIO的模式
        serverBootstrap.channel(NioServerSocketChannel.class);
        //3在这里配置具体数据接收方法的处理
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {

            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(new ServerHandler());
            }
        });
        // 引导类的配置信息
        serverBootstrap.option(ChannelOption.SO_BACKLOG,100);
        serverBootstrap.option(ChannelOption.SO_KEEPALIVE,true);
        //绑定端口
        ChannelFuture channelFuture = serverBootstrap.bind(8765).sync();

        //阻塞主线程 等等关闭
        channelFuture.channel().closeFuture().sync();

        bossGroup.shutdownGracefully();
        workGroup.shutdownGracefully();
    }
}
/**
 * Netty ServerHandler
 * 继承 ChannelInboundHandlerAdapter 设计模式 类适配器模式
 * Created by lyyz on 2018/5/25.
 */
public class ServerHandler extends ChannelHandlerAdapter{
    /**
     * 如果有写入方法,Netty 会自动是否ByteBuf
    * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf)msg;
        byte[] request = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(request);
        System.out.println(new String(request));
        ChannelFuture channelFuture = ctx.writeAndFlush(Unpooled.copiedBuffer("hello client".getBytes("utf-8")));
        channelFuture.addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
/**
 * Netty Client
 * Created by lyyz on 2018/5/25.
 */
public class Client {
    public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {
        // 客户端线程组 用于通讯
        EventLoopGroup workGroup = new NioEventLoopGroup();
        //客户端的Bootstrap 引导类
        Bootstrap bootstrap = new Bootstrap();
        // 绑定线程组
        bootstrap.group(workGroup);
        //设置通道类型
        bootstrap.channel(NioSocketChannel.class);
        //添加处理类
        bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(new ClientHandler());
            }
        });
        //设置客户端引导类 参数
        bootstrap.option(ChannelOption.SO_KEEPALIVE,true);
        // 客户端连接服务器
        ChannelFuture channelFuture = bootstrap.connect("127.0.0.1",8765).sync();
        // 通过ChannelFuture 得到管道 向管道内写入数据
        channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("hello server".getBytes("utf-8")));

        channelFuture.channel().closeFuture().sync();

        workGroup.shutdownGracefully();
    }
}
/**
 * Netty ClientHandler
 * 继承 ChannelInboundHandlerAdapter 设计模式 类适配器模式
 * Created by lyyz on 2018/5/25.
 */
public class ClientHandler extends ChannelHandlerAdapter{
    /**
     * 需要手动释放ByteBuf
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf byteBuf = (ByteBuf)msg;
            byte[] response = new byte[byteBuf.readableBytes()];
            byteBuf.readBytes(response);
            System.out.println(new String(response));
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

猜你喜欢

转载自blog.csdn.net/oYueYang1/article/details/80476053