標籤:system pac .net code system.in 輪詢 java nio 監聽 out
1 package com.slp.nio; 2 3 import org.junit.Test; 4 5 import java.io.IOException; 6 import java.net.InetSocketAddress; 7 import java.nio.ByteBuffer; 8 import java.nio.channels.SelectionKey; 9 import java.nio.channels.Selector; 10 import java.nio.channels.ServerSocketChannel; 11 import java.nio.channels.SocketChannel; 12 import java.time.LocalDateTime; 13 import java.util.Date; 14 import java.util.Iterator; 15 import java.util.Scanner; 16 17 /** 18 * Created by sanglp on 2017/3/2. 19 * 一、使用NIO完成網路通訊的三個核心 20 * 1、通道:負責串連 21 * |--java.nio.channels.channel介面 22 * |--SelectableChannel 23 * |--SocketChannel 24 * |--ServerSocketChannel 25 * |--DatagramChannel 26 * 27 * |--Pipe.SinkChannel 28 * |--Pipe.SourceChannel 29 * 2、緩衝區:負責資料的存取 30 * 3、選取器:是SelectableChannel的多工器,用於監控SelectableChannel的IO狀況 31 * 32 */ 33 public class TestNonBlockingNIO { 34 35 @Test 36 public void client() throws IOException { 37 //擷取通道 38 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898)); 39 //切換為非阻塞模式 40 socketChannel.configureBlocking(false); 41 //分配緩衝區 42 ByteBuffer buf = ByteBuffer.allocate(1024); 43 //發送資料給服務端 44 45 Scanner scanner = new Scanner(System.in); 46 while (scanner.hasNext()){ 47 String str = scanner.next(); 48 buf.put((new Date().toString()+"\n"+str).getBytes()); 49 buf.flip(); 50 socketChannel.write(buf); 51 buf.clear(); 52 } 53 54 55 //關閉通道 56 socketChannel.close(); 57 58 } 59 60 @Test 61 public void server() throws IOException { 62 //擷取通道 63 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 64 //切換非阻塞模式 65 serverSocketChannel.configureBlocking(false); 66 //綁定串連 67 serverSocketChannel.bind(new InetSocketAddress(9898)); 68 //擷取一個選取器 69 Selector selector = Selector.open(); 70 //將通道註冊到選取器上 並且指定監聽接收事件 71 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 72 //輪詢式的擷取選取器上已經準備就緒的事件 73 while (selector.select()>0){ 74 //擷取當前選取器中所有註冊的選擇鍵(已就緒的監聽事件) 75 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); 76 while (it.hasNext()){ 77 //擷取準備就緒的事件 78 SelectionKey sk = it.next(); 79 //判斷具體是什麼事件準備就緒 80 if(sk.isAcceptable()){ 81 //擷取額護短串連 82 SocketChannel socketChannel = serverSocketChannel.accept(); 83 //切換非阻塞模式 84 socketChannel.configureBlocking(false); 85 //將該通道註冊到選取器上 86 socketChannel.register(selector,SelectionKey.OP_READ); 87 }else if(sk.isReadable()){ 88 //擷取當前選取器上讀就緒狀態的通道 89 SocketChannel socketChannel = (SocketChannel) sk.channel(); 90 //讀取資料 91 ByteBuffer buffer = ByteBuffer.allocate(1024); 92 int len =0; 93 while ((len=socketChannel.read(buffer))>0){ 94 buffer.flip(); 95 System.out.println(new String(buffer.array(),0,len)); 96 buffer.clear(); 97 } 98 } 99 //取消選擇鍵100 it.remove();101 }102 }103 }104 }
【Java nio】 NonBlocking NIO