【Netty】NIO 网络通信 SelectionKey 常用 API 简介
文章目錄
- I . SelectionKey 簡介
 - II . SelectionKey 事件簡介
 - III . SelectionKey 常用 API 簡介
 
I . SelectionKey 簡介
1 . 通道注冊給選擇器 : 通道 ( Channel ) 注冊給 選擇器 ( Selector ) , 該通道就會納入到該 選擇器 ( Selector ) 管理范疇 , 選擇器 ( Selector ) 可以監(jiān)聽通道的事件 ;
被注冊的通道說明 : 這個 通道 ( Channel ) 即可以是 服務(wù)器套接字通道 ( ServerSocketChannel ) , 也可以是 套接字通道 ( SocketChannel ) ;
2 . 選擇器真實類型 : 選擇器 ( Selector ) 的 Selector 類是抽象類 , 其實例化的 真實類型是 WindowsSelectorImpl ;
3 . 選擇器 ( Selector ) 管理 通道 ( Channel ) 的方式 : 當(dāng) 通道 ( Channel ) 注冊給 選擇器 ( Selector ) 后 , 會返回 SelectionKey , 并將該 SelectionKey 放入 選擇器 ( Selector ) 中的 HashSet<SelectionKey> keys 集合中 , 這個集合中存放了所有注冊給該 選擇器 ( Selector ) 的通道所代表的 SelectionKey ;
4 . 獲取有事件發(fā)生的通道對應(yīng)的 SelectionKey 集合 : 當(dāng) 選擇器 ( Selector ) 監(jiān)聽到有事件發(fā)生 , 此時只能監(jiān)聽到事件發(fā)生的個數(shù) , 不知道具體的情況 ; 這就需要自己去 調(diào)用 選擇器 ( Selector ) 的 selectedKeys() 方法 , 此時返回的是 Set<SelectionKey> 類型的集合 , 因為同事可能有多個通道有事件發(fā)生 , 這里可以一次性處理多個通道的事件 ;
II . SelectionKey 事件簡介
SelectionKey 中的事件 , 就是 選擇器 ( Selector ) 注冊通道時 , 需要指明 , 監(jiān)聽這個通道的哪些事件 ;
SelectionKey 中定義了四種事件 : 數(shù)據(jù)讀取 ( OP_READ ) , 數(shù)據(jù)寫出 ( OP_WRITE ) , 連接 ( OP_CONNECT ) , 接受連接 ( OP_ACCEPT ) ;
1 . 接受連接 ( OP_ACCEPT ) 事件 :
① 適用場景 : 服務(wù)器端 服務(wù)器套接字通道 ( ServerSocketChannel ) 注冊該事件給 選擇器 ( Selector ) , 選擇器 ( Selector ) 可以監(jiān)聽到客戶端的連接請求 ;
② 代碼示例 : 下面的代碼作用是 , 將 ServerSocketChannel 通道的 SelectionKey.OP_ACCEPT 事件注冊給 選擇器 ( Selector ) , 當(dāng)有客戶端連接服務(wù)器的時候 , 就會觸發(fā) 選擇器 的監(jiān)聽方法 ;
//將 serverSocketChannel 通道注冊給 選擇器 ( Selector ), 這里注冊連接事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);③ OP_ACCEPT 常量原型 : 該常量定義在 SelectionKey.java 類中 , 該值的大小是 1 << 4 , 0b10000 ( 二進(jìn)制 ) , 0x10 ( 十六進(jìn)制 ) , 16 ( 十進(jìn)制 ) ;
/*** Operation-set bit for socket-accept operations.** <p> Suppose that a selection key's interest set contains* <tt>OP_ACCEPT</tt> at the start of a <a* href="Selector.html#selop">selection operation</a>. If the selector* detects that the corresponding server-socket channel is ready to accept* another connection, or has an error pending, then it will add* <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its* selected-key set. </p>*/ public static final int OP_ACCEPT = 1 << 4;2 . 讀取數(shù)據(jù) ( OP_READ ) 事件 :
① 適用場景 : 服務(wù)器端 套接字通道 ( SocketChannel ) 注冊該事件給 選擇器 ( Selector ) , 選擇器 ( Selector ) 可以監(jiān)聽到客戶端的 數(shù)據(jù)寫入到服務(wù)器 , 也就是說 服務(wù)器端需要執(zhí)行 讀取數(shù)據(jù) 的工作 ;
② 代碼示例 : 下面的代碼作用是 , 將 SocketChannel 通道的 SelectionKey.OP_READ 事件注冊給 選擇器 ( Selector ) , 當(dāng)有客戶端上傳數(shù)據(jù)的時候 , 就會觸發(fā) 選擇器 的監(jiān)聽方法 ;
//注冊通道 : 將 SocketChannel 通道注冊給 選擇器 ( Selector ) //關(guān)注事件 : 關(guān)注事件時讀取事件, 服務(wù)器端從該通道讀取數(shù)據(jù) //關(guān)聯(lián)緩沖區(qū) : sc.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));③ OP_READ 常量原型 : 該常量定義在 SelectionKey.java 類中 , 該值的大小是 1 << 0 , 0b1 ( 二進(jìn)制 ) , 0x1 ( 十六進(jìn)制 ) , 1 ( 十進(jìn)制 ) ;
/*** Operation-set bit for read operations.** <p> Suppose that a selection key's interest set contains* <tt>OP_READ</tt> at the start of a <a* href="Selector.html#selop">selection operation</a>. If the selector* detects that the corresponding channel is ready for reading, has reached* end-of-stream, has been remotely shut down for further reading, or has* an error pending, then it will add <tt>OP_READ</tt> to the key's* ready-operation set and add the key to its selected-key set. </p>*/ public static final int OP_READ = 1 << 0;3 . 寫出數(shù)據(jù) ( OP_WRITE ) 事件 :
① 適用場景 : 將通道 ( Channel ) 注冊給 選擇器 ( Selector ) , 注冊該 寫出數(shù)據(jù) ( OP_WRITE ) 事件 , 如果選擇器觸發(fā)該事件 , 表示該 向該 通道 ( Channel ) 寫出數(shù)據(jù)了 ;
② OP_WRITE 常量原型 : 該常量定義在 SelectionKey.java 類中 , 該值的大小是 1 << 2 , 0b100 ( 二進(jìn)制 ) , 0x4 ( 十六進(jìn)制 ) , 4 ( 十進(jìn)制 ) ;
/*** Operation-set bit for write operations.** <p> Suppose that a selection key's interest set contains* <tt>OP_WRITE</tt> at the start of a <a* href="Selector.html#selop">selection operation</a>. If the selector* detects that the corresponding channel is ready for writing, has been* remotely shut down for further writing, or has an error pending, then it* will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its* selected-key set. </p>*/ public static final int OP_WRITE = 1 << 2;4 . 連接 ( OP_CONNECT ) 事件 :
① 適用場景 : 將通道 ( Channel ) 注冊給 選擇器 ( Selector ) , 注冊該 連接 ( OP_CONNECT ) 事件 , 如果選擇器觸發(fā)該事件 , 表示該 發(fā)起網(wǎng)絡(luò) Socket 連接了 ;
② OP_WRITE 常量原型 : 該常量定義在 SelectionKey.java 類中 , 該值的大小是 1 << 3 , 0b1000 ( 二進(jìn)制 ) , 0x8 ( 十六進(jìn)制 ) , 8 ( 十進(jìn)制 ) ;
/*** Operation-set bit for socket-connect operations.** <p> Suppose that a selection key's interest set contains* <tt>OP_CONNECT</tt> at the start of a <a* href="Selector.html#selop">selection operation</a>. If the selector* detects that the corresponding socket channel is ready to complete its* connection sequence, or has an error pending, then it will add* <tt>OP_CONNECT</tt> to the key's ready set and add the key to its* selected-key set. </p>*/ public static final int OP_CONNECT = 1 << 3;III . SelectionKey 常用 API 簡介
1 . 獲取 NIO 三大組件 選擇器 ( Selector ) , 通道 ( Channel ) , 緩沖區(qū) ( Buffer ) 方法 :
① 獲取 選擇器 ( Selector ) : Selector selector() , 調(diào)用該方法獲取對應(yīng)的 選擇器 ( Selector ) ;
② 獲取 通道 ( Channel ) : SelectableChannel channel() , 調(diào)用該方法 獲取對應(yīng)綁定的 通道 ( Channel ) ;
③ 獲取 緩沖區(qū) ( Buffer ) : Object attach(Object ob) , 調(diào)用該方法 獲取 注冊的 通道 ( Channel ) 對應(yīng)的 緩沖區(qū) ( Buffer ) ;
④ 代碼示例 : 這是上一篇博客中 NIO 通信案例中的 服務(wù)器端的部分代碼 , 涉及到了獲取 通道 和 緩沖區(qū) 操作 ;
//獲取 通道 ( Channel ) : 通過 SelectionKey 獲取 SocketChannel socketChannel = (SocketChannel) key.channel(); //獲取 緩沖區(qū) ( Buffer ) : 獲取到 通道 ( Channel ) 關(guān)聯(lián)的 緩沖區(qū) ( Buffer ) ByteBuffer byteBuffer = (ByteBuffer) key.attachment();2 . 事件相關(guān)的方法 :
① 設(shè)置或更改監(jiān)聽事件 : interestOps(int ops) , 設(shè)置 或 改變 選擇器 ( Selector ) 關(guān)聯(lián)的事件 ;
② 判定事件類型 :
- 是否是 OP_READ 事件 : boolean isReadable() ;
 - 是否是 OP_WRITE 事件 : boolean isWritable() ;
 - 是否是 OP_CONNECT 事件 : boolean isConnectable() ;
 - 是否是 OP_ACCEPT 事件 : boolean isAcceptable() ;
 
總結(jié)
以上是生活随笔為你收集整理的【Netty】NIO 网络通信 SelectionKey 常用 API 简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 【Netty】NIO 选择器 ( Sel
 - 下一篇: 【Android】Handler 机制