初対面のNIO

8048 ワード

なぜNIOを使うのか
NIO(  IO),     IO    IO,     OutputStream  InputStream            ,     ,     CPU    ,                         。                           ,        HTTP            ,     Web  。         ,     NIO。

IOとNIOの違い
IO              NIO 
ストリームに向かう        バッファに向かう 
ブロックIO       非ブロックIO 
なし             セレクタ
NIO
初対面のNIO
まずiteyeのある大神の返事を引用してNIOについてのまとめ:
ChannelチャネルBufferバッファSelectorはNIOの3つのコア部分である. 
セレクタの中でChannelは以前のストリームに対応しており、Bufferは新しいものではなく、Selectorはnioが非同期の非閉塞モードを使用できるために加わったものです.以前の流れはいつも詰まっていて、1つのスレッドがそれを操作すれば、他の操作は詰まっていて、水道管にバルブがないことに相当して、あなたが手を伸ばして水を受け取る時、水が着いていなくても、あなたは水(流)にエネルギーを消費します.
NioのChannelの加入は、蛇口(バルブがある)を増やしたことに相当し、1つの水道管の水しか受けられないが、交代策に依存し、水量が少ない場合、各水道管から流れる水は、適切に受け入れられる.この肝心な点は、1つの給水工を増やしたこと、つまりSelectorについて、彼が協調を担当していることだ.つまりどの水道管に水が入っているかを見ると、現在の水道管の水がある程度届いているときは、一時的に現在の蛇口を閉めて、別の蛇口を開けてみます(水があるかどうか見てみましょう).
他の人が水を使う必要があるときは、直接水を受け取るのではなく、バケツが水を受け取る工を前提にしています.このバケツはBufferです.つまり、他の人も待つかもしれませんが、現場で待つのではなく、家に帰って待つことができます.他のことをしてもいいです.水がいっぱいになったら、水を受け取る組合が知らせます.
実は非常に現在の社会の分業の細分化の現実に近くて、既存の資源を統合して合併の効果を達成する1種のとても経済的な手段で、すぐにシリアル処理に来るのではありませんて、それは最も簡単ですが、しかし最も資源を浪費する方式です.
NIOの原理
NIO        Selector,         ,          socketchannel  Selector,         ,       ,      ,    SelectionKey,      Key,            socketchannel,  ,     Channel     ,  ,      ,            。

Selector                channel     ,     (        ),       channel         ,      ,        ,      ,              channel   。

NIO例
NIO例1
RandomAccessFile aFile = new RandomAccessFile("/Users/wjk/myproject/test/IO/src/main/resources/io.txt", "rw");
        //     
        FileChannel channel = aFile.getChannel();
        //       
        ByteBuffer buffer = ByteBuffer.allocate(43);
        //        
        int bytesRead = channel.read(buffer);
        if (bytesRead != -1) {
            System.out.println("read: " + bytesRead);
            //            (         )
            buffer.flip();
            //       
            while (buffer.hasRemaining()) {
                System.out.println((char) buffer.get());
            }
            //      
            //compact(          )
            buffer.clear();
            bytesRead = channel.read(buffer);
        }
        aFile.close();

NIO例2
/**
*     
**/
public class NIOServer {
    //     
    private Selector selector;

    /**
     *     ServerSocket  ,              
     *
     * @param port       
     * @throws IOException
     */
    public void initServer(int port) throws IOException {
        //     ServerSocket  
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        //         
        serverChannel.configureBlocking(false);
        //        ServerSocket   port  
        serverChannel.socket().bind(new InetSocketAddress(port));
        //          
        this.selector = Selector.open();
        //            ,       SelectionKey.OP_ACCEPT  ,      ,
        //       ,selector.select()   ,        selector.select()     。
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    /**
     *          selector           ,   ,     
     *
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public void listen() throws IOException {
        System.out.println("       !");
        //     selector
        while (true) {
            //         ,    ;  ,        
            selector.select();
            //   selector         ,          
            Iterator ite = this.selector.selectedKeys().iterator();
            while (ite.hasNext()) {
                SelectionKey key = (SelectionKey) ite.next();
                //      key,      
                ite.remove();
                //          
                if (key.isAcceptable()) {
                    ServerSocketChannel server = (ServerSocketChannel) key
                            .channel();
                    //            
                    SocketChannel channel = server.accept();
                    //       
                    channel.configureBlocking(false);

                    //              
                    channel.write(ByteBuffer.wrap(new String("           ").getBytes()));
                    //           ,             ,           。
                    channel.register(this.selector, SelectionKey.OP_READ);

                    //         
                } else if (key.isReadable()) {
                    read(key);
                }

            }

        }
    }

    /**
     *                 
     *
     * @param key
     * @throws IOException
     */
    public void read(SelectionKey key) throws IOException {
        //         :       Socket  
        SocketChannel channel = (SocketChannel) key.channel();
        //         
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        channel.read(buffer);
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("       :" + msg);
        ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes());
        channel.write(outBuffer);//          
    }

    /**
     *        
     *
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        NIOServer server = new NIOServer();
        server.initServer(8001);
        server.listen();
    }
}

/**
*    
**/
public class NIOClient {
    //     
    private Selector selector;

    /**
     *     Socket  ,              
     * @param ip        ip
     * @param port            
     * @throws IOException
     */
    public void initClient(String ip,int port) throws IOException {
        //     Socket  
        SocketChannel channel = SocketChannel.open();
        //         
        channel.configureBlocking(false);
        //          
        this.selector = Selector.open();

        //         ,             ,   listen()    
        // channel.finishConnect();      
        channel.connect(new InetSocketAddress(ip,port));
        //            ,       SelectionKey.OP_CONNECT  。
        channel.register(selector, SelectionKey.OP_CONNECT);
    }

    /**
     *          selector           ,   ,     
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    public void listen() throws IOException {
        //     selector
        while (true) {
            selector.select();
            //   selector         
            Iterator ite = this.selector.selectedKeys().iterator();
            while (ite.hasNext()) {
                SelectionKey key = (SelectionKey) ite.next();
                //      key,      
                ite.remove();
                //       
                if (key.isConnectable()) {
                    SocketChannel channel = (SocketChannel) key
                            .channel();
                    //       ,     
                    if(channel.isConnectionPending()){
                        channel.finishConnect();

                    }
                    //       
                    channel.configureBlocking(false);

                    //              
                    channel.write(ByteBuffer.wrap(new String("           ").getBytes()));
                    //           ,             ,           。
                    channel.register(this.selector, SelectionKey.OP_READ);

                    //         
                } else if (key.isReadable()) {
                    read(key);
                }

            }

        }
    }
    /**
     *                 
     * @param key
     * @throws IOException
     */
    public void read(SelectionKey key) throws IOException{
        //     read    
    }


    /**
     *        
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        NIOClient client = new NIOClient();
        client.initClient("localhost",8001);
        client.listen();
    }

}