netty(二):netty基础

简介

  • netty是一个Java开源框架。提供异步的、事件驱动的网络应用程序的框架和工具,用以快速开发高性能、高可用的网络服务器和客户端程序。

  • netty是一个NIO客户端、服务端框架,允许快速简单的开发网络应用程序。

优点

  • api使用简单,开发门槛低。
  • 功能强大,预置了很多编解码功能,支持多种主流协议。
  • 定制功能强,可以通过ChannelHandler对通信框架进行灵活的扩展。
  • 性能高,通过与其他业界主流的NIO框架相比,netty综合性能最优。
  • 成熟、稳定,netty已经修复了已经发现的所有bug。
  • 社区活跃
  • 经历了很多商用考验。

入门代码

public class NettyServer {

    public static void main(String[] args) {
        //服务端默认端口
        int port = 8080;
        new NettyServer().bind(port);
    }

    public void bind(int port) {
        //1、用于服务端接收客户端的链接
        EventLoopGroup parentGroup = new NioEventLoopGroup();
        //2、用于进行SocketChannel的网络读写
        EventLoopGroup childGroup = new NioEventLoopGroup();

        //netty用于启动NIO服务器的启动类
        ServerBootstrap bootstrap = new ServerBootstrap();
        //将两个NIO线程组传入辅助启动类中
        bootstrap.group(parentGroup, childGroup)
                //设置创建的Channel为NioServerSocketChannel类型
                .channel(NioServerSocketChannel.class)
                //配置NioServerSocketChannel的TCP参数
                .option(ChannelOption.SO_BACKLOG, 1024)
                //设置绑定IO事件的处理类
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) {
                        //创建NIOSocketChannel成功后,在进行初始化时,将它的ChannelHandler设置到ChannelPipeline中,用于处理网络IO事件
                        ch.pipeline().addLast(new NettyServerHandler());
                    }
                });
        try {
            //绑定端口,同步等待成功(sync():同步阻塞方法,等待bind操作完成才继续)
            //ChannelFuture主要用于异步操作的通知回调
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            System.out.println("服务端启动在8080端口。");
            //等待服务端监听端口关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //优雅退出,释放线程池资源
            parentGroup.shutdownGracefully();
            childGroup.shutdownGracefully();
        }
    }
}

public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        byte[] req = new byte[byteBuf.readableBytes()];
        //将buf中数据写入req
        byteBuf.readBytes(req);
        String body = new String(req, "utf-8");
        System.out.println("The time server(Thread:" + Thread.currentThread() + ") receive order : " + body);
        String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new Date(System.currentTimeMillis()).toString() : "BAD ORDER";

        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        //将待发送的消息放到发送缓存数组中
        ctx.writeAndFlush(resp);
    }
}
public class NettyClient {

    public static void main(String[] args) {
        new NettyClient().connect("127.0.0.1", 8080);
    }

    public void connect(String host, int port) {
        //配置客户端NIO线程组
        EventLoopGroup group = new NioEventLoopGroup();
        //配置客户端NIO线程组
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    //创建NIOSocketChannel成功后,在进行初始化时,将它的ChannelHandler设置到ChannelPipeline中,用于处理网络IO事件
                    protected void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });
        try {
            //发起异步连接操作
            ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
            //等待客户端链路关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    /**
     * 向服务器发送指令
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        byte[] req = "QUERY TIME ORDER".getBytes();
        ByteBuf firstMessage = Unpooled.buffer(req.length);
        firstMessage.writeBytes(req);
        ctx.writeAndFlush(firstMessage);
    }

    /**
     * 接收服务器的响应
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        //buf.readableBytes():获取缓冲区中可读的字节数;
        //根据可读字节数创建数组
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("Now is : " + body);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //释放资源
        ctx.close();
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值