3.Netty编程-入门

  Netty是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。(这里的异步和异步io不是一个概念)

一、Netty的优势

使用NIO开发网络应用,会面临很多困难:
1.工作量大,bug多。
2.需要解决TCP传输的问题,比如粘包、半包等。
3.NIO的epoll有bug,会空轮训导致cpu占用100%,Netty的作者用其他方法解决了这个问题。
4.对api进行了增强。

二、Netty的简单示例

2.1 client发送数据给服务端

服务器代码:

public static void main(String[] args) {
        //1.启动器,负责组装netty组件,启动服务器
        new ServerBootstrap()
                //2.多个EventLoop,处理不同的事件
                .group(new NioEventLoopGroup())
                //3.选择服务器的ServerSocketChannel实现
                .channel(NioServerSocketChannel.class)
                //4.worker逻辑处理
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        //5.将bytebuffer转为字符串
                        nioSocketChannel.pipeline().addLast(new StringDecoder());
                        nioSocketChannel.pipeline().addLast(new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                System.out.println(msg);
                            }
                        });
                    }
                }).bind(8080);
    }

客户端代码:

public static void main(String[] args) throws InterruptedException {
        //1.启动器,负责组装netty组件,启动服务器
        new Bootstrap()
                //2.添加EventLoop
                .group(new NioEventLoopGroup())
                //3.选择客户端的SocketChannel
                .channel(NioSocketChannel.class)
                //4.worker逻辑处理
                .handler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        //5.将字符串转为bytebuffer
                        nioSocketChannel.pipeline().addLast(new StringEncoder());
                    }
                    //6.连接服务器
                }).connect(new InetSocketAddress("localhost", 8080))
                //阻塞方法,连接建立才会执行
                .sync()
                //拿到连接对象
                .channel()
                //7.发送数据
                .writeAndFlush("hello fucker!!!");
    }

2.2 组件分析

  • 把channel理解为数据的通道。
  • 把 msg理解为流动的数据,最开始输入是ByteBuf,但经过pipeline的加工,会变成其它类型对象,最后输出又变成 ByteBuf。
  • 把 handler理解为数据的处理工序。
    工序有多道,合在一起就是pipeline,pipeline负责发布事件(读、读取完成…)传播给每个handler,handler对自己感兴趣的事件进行处理(重写了相应事件处理方法)。
    handler 分Inbound和Outbound两类。
  • 把eventLoop理解为处理数据的工人
    工人可以管理多个channel的io操作,并且一旦工人负责了某个channel,就要负责到底(绑定)。工人既可以执行io操作,也可以进行任务处理,每位工人有任务队列,队列里可以堆放多个channel的待处理任务,任务分为普通任务、定时任务。
    工人按照pipeline顺序,依次按照handler的规划(代码)处理数据,可以为每道工序指定不同的工人。

2.3 eventloop

  EventLoop本质是一个单线程执行器(同时维护了一个Selector),里面有run方法处理Channel上源源不断的io 事件。它的继承关系比较复杂:

  • 一条线是继承自j.u.c.ScheduledExecutorService因此包含了线程池中所有的方法
  • 另—条线是继承netty自己的 OrderedEventExecutor,提供了boolean inEventLoop(Thread thread)方法判断一个线程是否属于此EventLoop,还提供了parent方法来看看自己属于哪EventLoopGroup。
      EventLoopGroup是一组EventLoop,Channel一般会调用EventLoopGroup的register方法来绑定其中一个EventLoop,后续这个Channel上的io事件都由此EventLoop来处理(保证了io事件处理时的线程安全)。EventLoopGroup继承自netty自己的 EventExecutorGroup,实现了lterable接口提供遍历EventLoop的能力。另有next方法获取集合中下一个EventLoop。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值