Bio、Nio、Aio的用法系列之NIO客户端(三)

NIO客户端的实现

上一篇文章我们提到了NIO,大家应该对NIO有了一定的了解,接下来我们继续学习NIO的客户端实现

1、代码展示

首先我们还是先启动一个线程

publicclassNioServer {
publicstaticvoidmain(String [] args){
   //启动一个线程
   new Thread(new NioServerHandle()).start();

}

}

处理类

publicclassNioServerHandleimplementsRunnable{private ServerSocketChannel serverSocketChannel;
private Selector selector;
boolean stop  = false;
//初始化注册
publicNioServerHandle(){
   try {
       //获取ServerSocketChannel对象
       serverSocketChannel = ServerSocketChannel.open();
       //绑定ip
       serverSocketChannel.socket().bind(new InetSocketAddress(“127.0.0.1”,8989));
       //设置为非阻塞
       serverSocketChannel.configureBlocking(false);
       //获取Selector
       selector = Selector.open();
       //将管道注册到多路复用器selector上
       serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
   } catch (IOException e) {
       e.printStackTrace();
       System.exit(1);
   }
}
publicvoidstop(){
   this.stop = true;
}
@Override
publicvoidrun(){
   //轮询key
   while (!stop){
       try {
           //设置超时时间
           selector.select(1000);
           //获取所有key
           Set<selectionkey> selectionKeys = selector.selectedKeys();
           //遍历
           Iterator</selectionkey><selectionkey> it = selectionKeys.iterator();
           SelectionKey selectionKey = null;
           while (it.hasNext()){
               selectionKey = it.next();
               //获取到就绪数组进行操作,并移除
               it.remove();
               try {
                   handle(selectionKey);
               }catch (Exception e){
                   selectionKey.cancel();
                   selectionKey.channel().close();
               }
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}
/**
* 处理
* @param key
* @throws Exception
*/
publicvoidhandle(SelectionKey key)throws Exception{
   if (key.isValid()){
       if (key.isAcceptable()){
           //获取ServerSocketChannel
           ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
           //接受请求
           SocketChannel sc = ssc.accept();
           //设置为非阻塞
           sc.configureBlocking(false);
           //注册到多路复用器
           sc.register(selector,SelectionKey.OP_READ);
       }
       //read data
       if (key.isReadable()){
           //得到SocketChannel
           SocketChannel sc = (SocketChannel) key.channel();
           //设置字节缓冲区
           ByteBuffer readBuffer = ByteBuffer.allocate(1024);
           //将通道的数据读取码流
           int readByte = sc.read(readBuffer);
           //对于大于0的情况进行编解码
           if (readByte > 0){
               //将当前的缓冲区的limit设置为0,让后面进行读取
               readBuffer.flip();
               //根据缓冲区的可读大小设置字节数组
               byte [] bytes = newbyte[readBuffer.remaining()];
               //get将读取的数据放入字节数组
               readBuffer.get(bytes);
               //将字节数组按照UTF-8的格式输出到body
               String body = new String(bytes,“UTF-8”);
               System.out.print(“The Time server recevive order:”+body);
               String currentTime = “query”.equals(body)?new java.util.Date(System.currentTimeMillis()).toString():“No”;
               //进行输出操作
               doWrite(sc,currentTime);
           }elseif (readByte < 0 ){
               key.cancel();
               sc.close();
           }else {
           }
       }
   }
}
/**
* 将数据返回给客户端
* @param sc
* @param currentTime
* @throws Exception
*/
publicvoiddoWrite(SocketChannel sc,String currentTime)throws Exception{
   if (currentTime != null && currentTime.trim().length() > 0){
       //转换为字节数组,放到缓冲区
       byte [] bytes = currentTime.getBytes();
       ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
       byteBuffer.put(bytes);
       byteBuffer.flip();
       sc.write(byteBuffer);
   }
}}

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » Bio、Nio、Aio的用法系列之NIO客户端(三)

    Leave a Reply

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多