zoukankan      html  css  js  c++  java
  • Android开发进阶之NIO非阻塞包(四)

    今天我们通过一个实例详细讲解下AndroidNIO非阻塞服务器的开发,对于客户端而言Android123不推荐使用NIO,毕竟NIO相对于传统IO较为复杂,最重要的NIO是为了解决多线程并发问题而解决的技术,可能会因为管理和复杂性降低最终的结果,毕竟NIOJava的,相关的类型比较难控制,对于客户端而言我们可以使用C++JavaC#甚至Flash Action Script来编写。

     

        下面我们以一个简单的Echo Server为例子来分析

     

     import java.io.IOException;

    import java.net.InetSocketAddress;

    import java.nio.ByteBuffer;

    import java.nio.CharBuffer;

    import java.nio.channels.SelectionKey;

    import java.nio.channels.Selector;

    import java.nio.channels.ServerSocketChannel;

    import java.nio.channels.SocketChannel;

    import java.nio.charset.Charset;

    import java.nio.charset.CharsetDecoder;

    import java.nio.charset.CharsetEncoder;

    import java.util.Iterator;

     

    public class Server {

     

     public static void main(String[] args) {

      Selector selector = null;

      ServerSocketChannel ssc = null;

      try {

          selector = Selector.open(); //实例化selector

          ssc = ServerSocketChannel.open(); //实例化ServerSocketChannel 对象

     

          ssc.socket().bind(new InetSocketAddress(1987)); //绑定端口为1987

     

          ssc.configureBlocking(false); //设置为非阻塞模式

          ssc.register(selector, SelectionKey.OP_ACCEPT); //注册关心的事件,对于Server来说主要是accpet

     

     

       while (true) {

       int n= selector.select(); //获取感兴趣的selector数量

       if(n<1)

              continue; //如果没有则一直轮训检查

        Iterator<SelectionKey> it = selector.selectedKeys().iterator(); //有新的链接,我们返回一个SelectionKey集合

        while (it.hasNext()) {

         SelectionKey key = it.next(); //使用迭代器遍历

         it.remove(); //删除迭代器

     

         if (key.isAcceptable()) { //如果是我们注册的OP_ACCEPT事件

          ServerSocketChannel ssc2 = (ServerSocketChannel) key.channel();

          SocketChannel channel = ssc2.accept();

          channel.configureBlocking(false); //同样是非阻塞

          channel.register(selector, SelectionKey.OP_READ); //本次注册的是read事件,即receive接受

     

          System.out.println("CWJ Client :" + channel.socket().getInetAddress().getHostName() + ":"  + channel.socket().getPort());

         }

     

        else if (key.isReadable()) { //如果为读事件

     

          SocketChannel channel = (SocketChannel) key.channel();

     

          ByteBuffer buffer = ByteBuffer.allocate(1024); //1KB的缓冲区

          channel.read(buffer); //读取到缓冲区

          buffer.flip(); //准备写入

          System.out.println("android123 receive info:" + buffer.toString());

     

          channel.write(CharBuffer.wrap("it works".getBytes())); //返回给客户端

         }

        }

       }

      } catch (IOException e) {

       e.printStackTrace();

      } finally {

       try {

        selector.close();

        server.close();

       } catch (IOException e) {

       }

      }

     }

    }

     

     上面是比较简单的框架,里面存在很多问题,Android123将在下次详细阐述下,上面或者说国内有关NIO资料中的通病,如果你看过MinaGlassFish的源码,你可能就知道上面的问题大于10种,有关框架的bug占了大多数,作为服务器而言很容易CPU超过100%

     

  • 相关阅读:
    ZAB 和 Paxos 算法的联系与区别?
    Spring支持的ORM?
    解释对象/关系映射集成模块?
    哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?
    我们能自己写一个容器类,然后使用 for-each 循环码?
    Struts2的Action中获取request对象的几种方式?
    Chroot 特性?
    String是最基本的数据类型吗?
    @Autowired 注解?
    比较HQL、Criteria、Native-SQL这三者做查询的区别,以及应该如何进行选择?
  • 原文地址:https://www.cnblogs.com/cpcpc/p/2123006.html
Copyright © 2011-2022 走看看