NIOブロッキングと非ブロッキング

38393 ワード

NIOの非ブロッキングモード
NIOがコアを完成するものはセレクタであり、Selector、セレクタは主に各伝送データのチャネルをセレクタに登録し、セレクタはこれらのIOの状態(読み取り、書き込み、接続状態)を監視し、セレクタでチャネルの状況を監視し、すべてのスレッドの準備が整うのを待っている間に、セレクタはタスクをサービス側の1つ以上のスレッドに割り当てて実行する.
NIOがネットワーク通信を完了する3つのコア
1.チャンネル(Channel):接続担当
java.nio.channels.Channelインタフェース:
SelectChannelインタフェースの下には、SocketChannel、ServerSocketChannel、DatagramChannelがあります.
​ pipe.SinkChannelとPipeSourceChannel
2.バッファ(Buffer):データのアクセスを担当する
3.セレクタ(Selector):SelectableChannelの多重化器であり、SelectableChannelのIO状況を監視する
ブロックIOコード
package com.nio02;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class TestBlockingNIO {
    //   
    @Test
    public void client() throws IOException {
        //1.     
        SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));

        FileChannel inChannel = FileChannel.open(Paths.get("a.txt"), StandardOpenOption.READ);

        //2.           
        ByteBuffer buf = ByteBuffer.allocate(1024);

        //3.       ,       
        while (inChannel.read(buf) != -1) {
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        }

        //4.     
        inChannel.close();
        sChannel.close();
    }

    //   
    @Test
    public void server() throws IOException {
        //1.     
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        FileChannel outChannel = FileChannel.open(Paths.get("a2.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        //2.     
        ssChannel.bind(new InetSocketAddress(9898));

        //3.           
        SocketChannel sChannel = ssChannel.accept();

        //4.           
        ByteBuffer buf = ByteBuffer.allocate(1024);

        //5.         ,      
        while (sChannel.read(buf)!= -1){
            buf.flip();
            outChannel.write(buf);
            buf.clear();
        }
        //6.     
        sChannel.close();
        outChannel.close();
        ssChannel.close();
    }
}

そもそもブロックIOはshutdownOutput()が必要
package com.nio02;

import org.junit.Test;
import scala.reflect.io.Path;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class TestBlockingNIO2 {
    //   
    @Test
    public void server() throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();

        FileChannel outChannel = FileChannel.open(Paths.get("a.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);

        ssChannel.bind(new InetSocketAddress(9898));

        SocketChannel sChannel = ssChannel.accept();

        ByteBuffer buf = ByteBuffer.allocate(1024);

        while (sChannel.read(buf)!= -1){
            buf.flip();
            outChannel.write(buf);
            buf.clear();
        }

        //        
        buf.put("         !".getBytes());
        buf.flip();
        sChannel.write(buf);

        sChannel.close();
        outChannel.close();
        ssChannel.close();
    }

    //   
    @Test
    public void client() throws IOException {
        SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));

        FileChannel inChannel = FileChannel.open(Paths.get("a.txt"),StandardOpenOption.READ);

        ByteBuffer buf = ByteBuffer.allocate(1024);

        while (inChannel.read(buf) != -1){
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        }
        sChannel.shutdownOutput();
        //        
        int len = 0;
        while ((len = sChannel.read(buf))!= -1){
            buf.flip();
            System.out.println(new String(buf.array(),0,len));
            buf.clear();
        }
        inChannel.close();
        sChannel.close();
    }

}

非ブロックIO動作
//   
@Test
public void client() throws IOException{
	//1.     
	SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
	
	//2.        
	sChannel.configureBlocking(false);
	
	//3.           
	ByteBuffer buf = ByteBuffer.allocate(1024);
	
	//4.         
	Scanner scan = new Scanner(System.in);
	
	while(scan.hasNext()){
		String str = scan.next();
		buf.put((new Date().toString() + "
"
+ str).getBytes()); buf.flip(); sChannel.write(buf); buf.clear(); } //5. sChannel.close(); } // @Test public void server() throws IOException{ //1. ServerSocketChannel ssChannel = ServerSocketChannel.open(); //2. ssChannel.configureBlocking(false); //3. ssChannel.bind(new InetSocketAddress(9898)); //4. Selector selector = Selector.open(); //5. , “ ” ssChannel.register(selector, SelectionKey.OP_ACCEPT); //6. “ ” while(selector.select() > 0){ //7. “ ( )” Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while(it.hasNext()){ //8. “ ” SelectionKey sk = it.next(); //9. if(sk.isAcceptable()){ //10. “ ”, SocketChannel sChannel = ssChannel.accept(); //11. sChannel.configureBlocking(false); //12. sChannel.register(selector, SelectionKey.OP_READ); }else if(sk.isReadable()){ //13. “ ” SocketChannel sChannel = (SocketChannel) sk.channel(); //14. ByteBuffer buf = ByteBuffer.allocate(1024); int len = 0; while((len = sChannel.read(buf)) > 0 ){ buf.flip(); System.out.println(new String(buf.array(), 0, len)); buf.clear(); } } //15. SelectionKey it.remove(); } } }