上面這段代碼是書上關於Nio具體工作過程的代碼示例。其工作過程可以具體闡述如下: 其中有兩個關鍵的類:Channel和Selector,它們是NIO中的核心概念。其中Channel可類比為交通工具,而且是具體的交通工具,例如:汽車,自行車。而Selector則可以類比為車輛調度系統,負責車輛運行狀況 ...
1 public void selector() throws IOException { 2 ByteBuffer buffer = ByteBuffer.allocate(1024); 3 Selector selector = Selector.open(); 4 ServerSocketChannel ssc = ServerSocketChannel.open(); 5 ssc.configureBlocking(false);//設置為非阻塞模式 6 ssc.socket().bind(new InetSocketAddress(8080)); 7 ssc.register(selector, SelectionKey.OP_ACCEPT);//註冊監聽事件 8 while(true) { 9 Set selectorKeys = selector.selectorKeys();//取得所有key的集合 10 Iterator it = selectorKeys.iterator(); 11 while(it.hasNext()) { //檢查序列是否還有元素 12 SelectionKey key = (SelectionKey) it.next(); 13 if((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { 14 ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel(); 15 SocketChannel sc = ssChannel.accept();//接受到服務端的請求 16 sc.configureBlocking(false); 17 sc.register(selector,SelectionKey.OP_ACCEPT); 18 it.remove(); 19 } else if((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { 20 SocketChannel sc = (SocketChannel) key.channel; 21 while(true) { 22 buffer.clear(); 23 int n = sc.read(buffer);//讀取數據 24 if(n <= 0) { 25 break; 26 } 27 buffer.flip(); 28 } 29 it.remove(); 30 } 31 32 } 33 34 } 35 36 }
上面這段代碼是書上關於Nio具體工作過程的代碼示例。其工作過程可以具體闡述如下:
其中有兩個關鍵的類:Channel和Selector,它們是NIO中的核心概念。其中Channel可類比為交通工具,而且是具體的交通工具,例如:汽車,自行車。而Selector則可以類比為車輛調度系統,負責車輛運行狀況的監視和具體調度工作。
ServerSocketChannel類是針對面向流的偵聽套接字的可選擇通道,在服務端創建完此類實例後通過Socket()方法(獲取與此通道關聯的伺服器套接字)返回一個ServerSocket類的實例,在利用此實例的void bind(SocketAddress endpoint)方法將 ServerSocket
綁定到特定地址(IP 地址和埠號)。就像計程車公司的每輛計程車都要在公司註冊一樣,我們也需要將ServerSocketChannel的實例通過register()方法將此通道註冊到指定的選擇器。
然後調用Selector的selectedKeys方法來檢查已經註冊在這個選擇器上的所有通信通道是否有需要的事件發生,如果有某個事件發生,將會返回所有的SelectionKey,由於key.readyOps()獲取此鍵的 ready 操作集合,所以個人認為key.readyOps()&SelectionKey.OP_ACCEPT意思是此鍵的 ready 操作集合為ACCEPT狀態,即伺服器處於監聽狀態,通過這個對象的Channel方法就可以取得這個通信通道對象,然後調用accept()方法返回一個套接字通道,預設為阻塞狀態,也可以利用Channel方法取得的通信通道對象讀取通信的數據,而這裡讀取的數據是Buffer,這個Buffer是我們可以控制的緩衝器。