亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

小白也可以學會的Java NIO的Write事件

瀏覽:97日期:2022-08-11 13:55:05
目錄一、NIO Server端1.1 多路復用開發(fā)一般步驟1.2 解惑寫事件二、不使用事件三、使用事件四、NIO Client端一、NIO Server端1.1 多路復用開發(fā)一般步驟

//打開選擇器Selector selector = Selector.open();//打開通到ServerSocketChannel socketChannel = ServerSocketChannel.open();//配置非阻塞模型socketChannel.configureBlocking(false);//綁定端口socketChannel.bind(new InetSocketAddress(8080));//注冊事件,OP_ACCEPT只適用于ServerSocketChannel socketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) { selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iter = selectionKeys.iterator(); while(iter.hasNext()) {SelectionKey key = iter.next();if(key.isAcceptable()) { SocketChannel channel = ((ServerSocketChannel)key.channel()).accept(); channel.configureBlocking(false); channel.register(selector,SelectionKey.OP_READ);}if(key.isWritable()) {}if(key.isReadable()) { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); channel.read(readBuffer); readBuffer.flip(); // handler Buffer // 一般是響應客戶端的數(shù)據(jù) // 直接是write寫不就完事了嘛,為啥需要write事件? // channel.write(...)}iter.remove(); }}1.2 解惑寫事件

對NIO的寫操作:

為什么要注冊寫事件 何時注冊寫事件 為什么寫完之后要取消注冊寫事件

如果有channel在Selector上注冊了SelectionKey.OP_WRITE,在調(diào)用selector.select();時,系統(tǒng)會檢查內(nèi)核寫緩沖區(qū)是否可寫:

如果可寫,selector.select();立即返回,進入key.isWritable() 何時不可寫?比如緩沖區(qū)已滿,channel調(diào)用了shutdownOutPut等

當然除了注冊寫事件,你也可以在channel直接調(diào)用write(…),也可以將數(shù)據(jù)發(fā)出去,但這樣不夠靈活,而且可能浪費CPU。

比如服務端需要發(fā)送一個200M的Buffer,看看是否使用OP_WRITE事件的區(qū)別。

二、不使用事件

程序運行到這會等到200M文件發(fā)送完成后才繼續(xù)往下執(zhí)行,不符合異步事件模型的思想。若緩沖區(qū)一直處不可寫狀態(tài),則該過程一直在這里死循環(huán),浪費CPU。

// 200M的BufferByteBuffer buffer = .... while(buffer.hasRemaining()) { // 該方法只會寫入小于socket’s output buffer空閑區(qū)域的任何字節(jié)數(shù) // 并返回寫入的字節(jié)數(shù),可能是0字節(jié) channel.write(buffer);}三、使用事件

if(key.isReadable()) {// 200M Buffer ByteBuffer buffer = .... // 注冊寫事件 key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); // 綁定Buffer key.attach(buffer);}// 可寫分支if(key.isWritable()) { ByteBuffer buffer = (ByteBuffer) key.attachment(); SocketChannel channel = (SocketChannel) key.channel(); if (buffer.hasRemaining()) {channel.write(buffer) } else {// 發(fā)送完了就取消寫事件,否則下次還會進入寫事件分支(因為只要還可寫,就會進入)key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); }}

要觸發(fā)寫事件,需要先向 selector 注冊該通道的寫事件,跟注冊讀事件一樣,當?shù)讓訉懢彌_區(qū)有空閑就會觸發(fā)寫事件了,而一般來說底層的寫緩沖區(qū)大部分都是空閑的。所以一般只要注冊了寫事件,就會立馬觸發(fā)了,為了避免 cpu 空轉(zhuǎn),在寫操作完成后需要把寫事件取消掉,然后下次再有寫操作時重新注冊寫事件。

四、NIO Client端

開發(fā)的一般步驟

// 打開選擇器Selector selector = Selector.open();// 打開通道SocketChannel socketChannel = SocketChannel.open();// 配置非阻塞模型socketChannel.configureBlocking(false);// 連接ServersocketChannel.connect(new InetSocketAddress('127.0.0.1',8080));// 注冊事件socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);// 循環(huán)處理while (true) { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> iter = keys.iterator(); while(iter.hasNext()) {SelectionKey key = iter.next();if(key.isConnectable()) { // 連接建立或者連接建立不成功 SocketChannel channel = (SocketChannel) key.channel(); // 完成連接建立 if(channel.finishConnect()) { }}if(key.isReadable()) { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(500 * 1024 * 1024); buffer.clear(); channel.read(buffer); // buffer Handler}iter.remove(); }}

起初對OP_CONNECT事件還有finishConnect不理解,OP_CONNECT事件何時觸發(fā),特別是為什么要在key.isConnectable()分支里調(diào)用finishConnect方法后才能進行讀寫操作。

首先,在non-blocking模式下調(diào)用socketChannel.connect(new InetSocketAddress(“127.0.0.1”,8080));連接遠程主機,如果連接能立即建立就像本地連接一樣,該方法會立即返回true,否則該方法會立即返回false,然后系統(tǒng)底層進行三次握手建立連接。連接有兩種結(jié)果,一種是成功連接,第二種是異常,但是connect方法已經(jīng)返回,無法通過該方法的返回值或者是異常來通知用戶程序建立連接的情況,所以由OP_CONNECT事件和finishConnect方法來通知用戶程序。不管系統(tǒng)底層三次連接是否成功,selector都會被喚醒繼而觸發(fā)OP_CONNECT事件,如果握手成功,并且該連接未被其他線程關(guān)閉,finishConnect會返回true,然后就可以順利的進行channle讀寫。如果網(wǎng)絡(luò)故障,或者遠程主機故障,握手不成功,用戶程序可以通過finishConnect方法獲得底層的異常通知,進而處理異常。

到此這篇關(guān)于小白也可以學會的Java NIO的Write事件的文章就介紹到這了,更多相關(guān)Java NIO的Write事件內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲国产片 | 银杏视频影院在线看 | 国产一区二区影视 | 青青草一区国产97 | 亚洲高清国产一线久久 | 黄色在线免费网站 | 黄色成人在线网站 | 免费观看成人碰视频公开 | 色婷婷欧美 | 91精品国产爱久久久久久 | 在线播放一区二区精品产 | 国产亚洲精品视频中文字幕 | 亚洲色图综合网站 | 丁香六月婷婷精品免费观看 | 亚洲欧美一区二区三区久久 | 亚洲一区免费在线 | 国产一级做a爰片久久毛片男 | 日本视频中文字幕一区二区 | 中文国产成人精品少久久 | 丁香综合在线 | 欧美一级特黄aa大片婷婷 | 真正国产乱子伦高清对白 | 国产免费私拍一区二区三区 | 爱爱欧美| 欧美久久久久久久一区二区三区 | 亚洲在线一区二区 | 欧美精品1区 | 草草草在线视频 | 国内激情| 天天综合亚洲 | 欧美日韩一本大道香蕉欧美 | 精品国产电影 | 欧美久在线观看在线观看 | 黄色小视频网 | 国产精品美脚玉足在线 | 香蕉啪| 日韩中文字幕电影 | 久久久久久久99精品免费观看 | 精品欧美一区二区三区四区 | 青青草国产三级精品三级 | 午夜黄页网站在线播放 |