zoukankan      html  css  js  c++  java
  • Java NIO 笔记

    0. 存在多种通道,key.channel()返回的是该事件的宿主,如果key是OP_ACCEPT事件,则返回的会是ServerSocketChannel.

    1. SelectionKey.cancel  : cancel()方法是永久的注销SelectionKey.OPxxxx,并将其放入selector的canceled set中。在下一次调用select()方法的时候,这些键会从该选择器的所有键集中移除,它关联的信道也不在监听了(除非它又重新注册)。

    2.NIO HTTP Server Example :

    import java.io.*;
    
    import java.nio.*;
    
    import java.nio.channels.*;
    
    import java.util.Iterator;
    
    import java.net.*;
    
    
    
    public class NonblockingSingleFileHTTPServer {
    
    
    
      private ByteBuffer contentBuffer;
    
      private int port = 80;
    
    
    
      public NonblockingSingleFileHTTPServer(
    
       ByteBuffer data, String encoding, String MIMEType, int port) 
    
       throws UnsupportedEncodingException {
    
        
    
        this.port = port;
    
        String header = "HTTP/1.0 200 OK\r\n"
    
         + "Server: OneFile 2.0\r\n"
    
         + "Content-length: " + data.limit( ) + "\r\n"
    
         + "Content-type: " + MIMEType + "\r\n\r\n";
    
        byte[] headerData = header.getBytes("ASCII");
    
    
    
        ByteBuffer buffer = ByteBuffer.allocate(
    
         data.limit( ) + headerData.length);
    
        buffer.put(headerData);
    
        buffer.put(data);
    
        buffer.flip( );
    
        this.contentBuffer = buffer;
    
        
    
      }
    
      
    
      public void run( ) throws IOException {
    
      
    
        ServerSocketChannel serverChannel = ServerSocketChannel.open( );
    
        ServerSocket  serverSocket = serverChannel.socket( );
    
        Selector selector = Selector.open( );
    
        InetSocketAddress localPort = new InetSocketAddress(port);
    
        serverSocket.bind(localPort);
    
        serverChannel.configureBlocking(false);
        
        //服务端通道只注册accept事件
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
    
    
    
        while (true) {
    
        
    
          selector.select( );
          
          Iterator keys = selector.selectedKeys( ).iterator( );
    
          while (keys.hasNext( )) {
    
            SelectionKey key = (SelectionKey) keys.next( );
            //一定要删除已处理过的事件,否则下一次select仍然会提交给你
            keys.remove( );
    
            try {
    
              if (key.isAcceptable( )) {
    
                ServerSocketChannel server = (ServerSocketChannel) key.channel( );
    
                SocketChannel channel = server.accept( );
    
                channel.configureBlocking(false);
                //给客户端通道注册可读事件
                SelectionKey newKey = channel.register(selector, 
    
                                                       SelectionKey.OP_READ);
    
              }
    
              else if (key.isWritable( )) {
            	
            	
            	
                SocketChannel channel = (SocketChannel) key.channel( );
    
                ByteBuffer buffer = (ByteBuffer) key.attachment( );
                synchronized (buffer) {
    				
    			
                
               
                if (buffer.hasRemaining( )) {
                
                	//可写则写
                   channel.write(buffer);   
    
                }
    
                else {  // we're done
                	//写完关闭客户端连接
                    channel.close( );   
                	
                }
                }
    
              }
    
              else if (key.isReadable( )) {
    
                // Don't bother trying to parse the HTTP header.
    
                // Just read something.
    
                SocketChannel channel = (SocketChannel) key.channel( );
    
                ByteBuffer buffer = ByteBuffer.allocate(4096); 
    
                channel.read(buffer);
                //buffer.flip();
                //System.out.println(new String(buffer.array()));
    
                // switch channel to write-only mode
                
                
                //更改为只注册可写事件
    
                key.interestOps(SelectionKey.OP_WRITE);
    
                key.attach(contentBuffer.duplicate( ));
    
              }
    
            }
    
            catch (IOException ex) {
            	ex.printStackTrace();
            	
              //取消key所对应的事件
              key.cancel( );
    
              try {
            	  
                key.channel( ).close( );
    
              }
    
              catch (IOException cex) {
            	  cex.printStackTrace();
            	  
              }
    
            }
    
          }
    
        }
    
      }
    
      
    
      public static void main(String[] args) {
    
    
    	args = new String[]{"I:\\说明_Readme.html","801","gb2312"};
        if (args.length == 0) {
    
          System.out.println(
    
            "Usage: java NonblockingSingleFileHTTPServer file port encoding"); 
    
          return;
    
        }
    
          
    
        try {
    
          String contentType = "text/plain";
    
          if (args[0].endsWith(".html") || args[0].endsWith(".htm")) {
    
            contentType = "text/html";
    
          }
    
          
    
          FileInputStream fin = new FileInputStream(args[0]);
    
          FileChannel in = fin.getChannel( );
    
          ByteBuffer input = in.map(FileChannel.MapMode.READ_ONLY, 0, in.size( ));
    
            
    
          // set the port to listen on
    
          int port;
    
          try {
    
            port = Integer.parseInt(args[1]);
    
            if (port < 1 || port > 65535) port = 80;
    
          }  
    
          catch (Exception ex) {
    
            port = 80;
    
          }  
    
          
    
          String encoding = "ASCII";
    
          if (args.length > 2) encoding = args[2]; 
    
           
    
          NonblockingSingleFileHTTPServer server
    
           = new NonblockingSingleFileHTTPServer(
    
             input, encoding, contentType, port);
    
          server.run( );         
    
    
    
        }
    
        catch (Exception ex) {
    
          ex.printStackTrace( );
    
          System.err.println(ex);
    
        }
    
      
    
      }
    
    
    
    }
  • 相关阅读:
    测试工具PerfDog的使用
    1.人工智能解读与Python简介
    如何提高百度网盘下载速度小技巧(亲测有效!)
    学习方法
    字符串换行工具类/每隔几位插入指定字符串
    java对pdf文件加文字水印 itextpdf
    centos 7.6 安装jdk8
    1 elk软件的安装
    Springboot 2.2.1 与activeMq 集成2 topic 发布者,订阅者
    Springboot 2.2.1 与activeMq 集成2 queue 消息
  • 原文地址:https://www.cnblogs.com/yangyh/p/2165946.html
Copyright © 2011-2022 走看看