zoukankan      html  css  js  c++  java
  • 4 传输

    OIO和NIO写法大相径庭,但netty的阻塞和非阻塞的代码基本一致,

    public class NettyOioServer {
      public void server(int port)
          throws Exception {
        final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!
    ", Charset.forName("UTF-8")));
        EventLoopGroup group = new OioEventLoopGroup();
        try {
          //创建 ServerBootstrap
          ServerBootstrap b = new ServerBootstrap();
          b.group(group)
              //使用 OioEventLoopGroup以允许阻塞模式(旧的I/O)
              .channel(OioServerSocketChannel.class)
              .localAddress(new InetSocketAddress(port))
              //指定 ChannelInitializer,对于每个已接受的连接都调用它
              .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch)
                    throws Exception {
                  ch.pipeline().addLast(
                      //添加一个 ChannelInboundHandlerAdapter以拦截和处理事件
                      new ChannelInboundHandlerAdapter() {
                        @Override
                        public void channelActive(ChannelHandlerContext ctx) throws Exception {
                          ctx.writeAndFlush(buf.duplicate())
                              //将消息写到客户端,并添加 ChannelFutureListener,
                              //以便消息一被写完就关闭连接
                              .addListener(ChannelFutureListener.CLOSE);
                        }
                      });
                }
              });
          //绑定服务器以接受连接
          ChannelFuture f = b.bind().sync();
          f.channel().closeFuture().sync();
        } finally {
          //释放所有的资源
          group.shutdownGracefully().sync();
        }
      }
    public class NettyNioServer {
      public void server(int port) throws Exception {
        final ByteBuf buf = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!
    ", Charset.forName("UTF-8")));
        //为非阻塞模式使用NioEventLoopGroup
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
          //创建ServerBootstrap
          ServerBootstrap b = new ServerBootstrap();
          b.group(group).channel(NioServerSocketChannel.class)
              .localAddress(new InetSocketAddress(port))
              //指定 ChannelInitializer,对于每个已接受的连接都调用它
              .childHandler(new ChannelInitializer<SocketChannel>() {
                              @Override
                              public void initChannel(SocketChannel ch)
                                  throws Exception {
                                ch.pipeline().addLast(
                                    //添加 ChannelInboundHandlerAdapter以接收和处理事件
                                    new ChannelInboundHandlerAdapter() {
                                      @Override
                                      public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                        //将消息写到客户端,并添加ChannelFutureListener,
                                        //以便消息一被写完就关闭连接
                                        ctx.writeAndFlush(buf.duplicate())
                                            .addListener(ChannelFutureListener.CLOSE);
                                      }
                                    });
                              }
                            }
              );
          //绑定服务器以接受连接
          ChannelFuture f = b.bind().sync();
          f.channel().closeFuture().sync();
        } finally {
          //释放所有的资源
          group.shutdownGracefully().sync();
        }
      }
    }

    每个Channel 都将会被分配一个ChannelPipeline 和ChannelConfig

    ChannelConfig 包含了该Channel 的所有配置设置,并且支持热更新。由于特定的传输可能

    具有独特的设置,所以它可能会实现一个ChannelConfig 的子类型。

    ChannelHandler 的典型用途包括:

    将数据从一种格式转换为另一种格式;

    提供异常的通知;

    提供Channel 变为活动的或者非活动的通知;

    提供当Channel 注册到EventLoop 或者从EventLoop 注销时的通知;

    提供有关用户自定义事件的通知。

     

     

     

     

    零拷贝
    零拷贝(zero-copy)是一种目前只有在使用NIO 和Epoll 传输时才可使用的特性。它使你可以快速
    高效地将数据从文件系统移动到网络接口,而不需要将其从内核空间复制到用户空间,其在像FTP 或者
    HTTP 这样的协议中可以显著地提升性能。但是,并不是所有的操作系统都支持这一特性。特别地,它对
    于实现了数据加密或者压缩的文件系统是不可用的——只能传输文件的原始内容。反过来说,传输已被
    加密的文件则不是问题。
    4.3.2 Epoll—用于Linux 的本地非阻塞传输
    正如我们之前所说的,Netty 的NIO 传输基于Java 提供的异步/非阻塞网络编程的通用抽象。
    虽然这保证了Netty 的非阻塞API 可以在任何平台上使用,但它也包含了相应的限制,因为JDK
    为了在所有系统上提供相同的功能,必须做出妥协。
    Linux作为高性能网络编程的平台,其重要性与日俱增,这催生了大量先进特性的开发,其
    中包括epoll——一个高度可扩展的I/O事件通知特性。这个API自Linux内核版本2.5.442002)被
    引入,提供了比旧的POSIX select和poll系统调用①
    ① 参见Linux 手册页中的epoll(4):http://linux.die.net/man/4/epoll。
    更好的性能,同时现在也是Linux上非阻
    塞网络编程的事实标准。Linux JDK NIO API使用了这些epoll调用。
    Netty为Linux提供了一组NIO API,其以一种和它本身的设计更加一致的方式使用epoll,并
    且以一种更加轻量的方式使用中断。①
    如果你的应用程序旨在运行于Linux系统,那么请考虑利用
    这个版本的传输;你将发现在高负载下它的性能要优于JDK的NIO实现。
    这个传输的语义与在图4-2 所示的完全相同,而且它的用法也是简单直接的。相关示例参照
    代码清单4-4如果要在那个代码清单中使用epoll 替代NIO,只需要将NioEventLoopGroup
    替换为EpollEventLoopGroup , 并且将NioServerSocketChannel.class 替换为
    EpollServerSocketChannel.class 即可。

    Netty的OIO实现

     

     

  • 相关阅读:
    十七:CSS之CSS继承和层叠
    十六:CSS之CSS选择器之后代选择器、伪类选择器
    十五:CSS之CSS选择器之群组选择器、全局选择器
    十四:CSS之CSS选择器之标签选择器、类选择器、ID选择器
    Android开发技巧——ViewPager加View情况封装PagerAdapter的实现类
    JAVA知识笔记
    机器学习笔记
    设计模式学习
    Android小知识汇总
    判断GPS是否开启&转到设置GPS界面
  • 原文地址:https://www.cnblogs.com/lakeslove/p/13058261.html
Copyright © 2011-2022 走看看