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%

 

原文地址:https://www.cnblogs.com/cpcpc/p/2123006.html