摘要:非阻塞模式下方法在尚未讀取到任何數(shù)據(jù)時可能就返回了。非阻塞模式與選擇器非阻塞模式與選擇器搭配會工作的更好,通過將一或多個注冊到,可以詢問選擇器哪個通道已經(jīng)準備好了讀取,寫入等。
Java NIO中的SocketChannel是一個連接到TCP網(wǎng)絡套接字的通道。可以通過以下2種方式創(chuàng)建SocketChannel:
1.打開一個SocketChannel并連接到互聯(lián)網(wǎng)上的某臺服務器。 2.一個新連接到達ServerSocketChannel時,會創(chuàng)建一個SocketChannel。
打開 SocketChannel
下面是SocketChannel的打開方式:
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ServerSocket ss = serverSocketChannel.socket(); ss.bind(new InetSocketAddress("localhost", 9026));// 綁定地址
關(guān)閉 SocketChannel
當用完SocketChannel之后調(diào)用SocketChannel.close()關(guān)閉SocketChannel:
socketChannel.close();
從 SocketChannel 讀取數(shù)據(jù)
要從SocketChannel中讀取數(shù)據(jù),調(diào)用一個read()的方法之一。以下是例子:
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
首先,分配一個Buffer。從SocketChannel讀取到的數(shù)據(jù)將會放到這個Buffer中。
然后,調(diào)用SocketChannel.read()。該方法將數(shù)據(jù)從SocketChannel 讀到Buffer中。
read()方法返回的int值表示讀了多少字節(jié)進Buffer里。
如果返回的是-1,表示已經(jīng)讀到了流的末尾(連接關(guān)閉了)。
寫入 SocketChannel
寫數(shù)據(jù)到SocketChannel用的是SocketChannel.write()方法,該方法以一個Buffer作為參數(shù)。示例如下:
String newData = "New String to write to file..." + System.currentTimeMillis(); ByteBuffer buf = ByteBuffer.allocate(48); buf.clear(); buf.put(newData.getBytes()); buf.flip(); while(buf.hasRemaining()) { channel.write(buf); }
注意SocketChannel.write()方法的調(diào)用是在一個while循環(huán)中的。Write()方法無法保證能寫多少字節(jié)到SocketChannel。所以,我們重復調(diào)用write()直到Buffer沒有要寫的字節(jié)為止。
非阻塞模式
可以設置 SocketChannel 為非阻塞模式(non-blocking mode).設置之后,就可以在異步模式下調(diào)用connect(), read() 和write()了。
connect()
如果SocketChannel在非阻塞模式下,此時調(diào)用connect(),該方法可能在連接建立之前就返回了。為了確定連接是否建立,可以調(diào)用finishConnect()的方法。像這樣:
socketChannel.configureBlocking(false);//非阻塞 socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); while(! socketChannel.finishConnect() ){ //wait, or do something else... }
write()
非阻塞模式下,write()方法在尚未寫出任何內(nèi)容時可能就返回了。所以需要在循環(huán)中調(diào)用write()。
read()
非阻塞模式下,read()方法在尚未讀取到任何數(shù)據(jù)時可能就返回了。所以需要關(guān)注它的int返回值,它會告訴你讀取了多少字節(jié)。
非阻塞模式與選擇器
非阻塞模式與選擇器搭配會工作的更好,通過將一或多個SocketChannel注冊到Selector,可以詢問選擇器哪個通道已經(jīng)準備好了讀取,寫入等。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71756.html
摘要:編程核心是通道和選擇器,選擇器通過不斷輪詢,執(zhí)行對應的函數(shù)。所以我們需要捕獲這個異常,并且開始不斷重連。如果客戶端關(guān)閉那么服務器也要主動關(guān)閉他數(shù)據(jù)庫代碼及實體類如果還想實現(xiàn)數(shù)據(jù)庫方面代碼,私我 ...
摘要:為解決這問題,我們發(fā)現(xiàn)元兇處在一線程一請求上,如果一個線程能同時處理多個請求,那么在高并發(fā)下性能上會大大改善。這樣一個線程可以同時發(fā)起多個調(diào)用,并且不需要同步等待數(shù)據(jù)就緒。表示當前就緒的事件類型。 JAVA NIO 一步步構(gòu)建I/O多路復用的請求模型 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog 文章一:JAVA ...
摘要:通道可以異步讀寫。使用的方法讀取數(shù)據(jù)創(chuàng)建一個讀數(shù)據(jù)緩沖區(qū)對象從通道中讀取數(shù)據(jù)使用的方法寫入數(shù)據(jù)創(chuàng)建一個寫數(shù)據(jù)緩沖區(qū)對象寫入數(shù)據(jù)關(guān)閉完成使用后,您必須關(guān)閉它。五提供了一種被稱為的新功能,也稱為本地矢量。功能是通道提供的并不是。 歷史回顧: Java NIO 概覽 Java NIO 之 Buffer(緩沖區(qū)) 其他高贊文章: 面試中關(guān)于Redis的問題看這篇就夠了 一文輕松搞懂redis集...
摘要:是什么就不在此文展開,這篇主要來介紹下我們要怎樣通過來構(gòu)建一個服務客戶端程序的。的通信完全依賴與,數(shù)據(jù)的寫入和讀取都是通過從中寫入讀取。和上的調(diào)用一樣的功能,監(jiān)聽已經(jīng)注冊在上面的文件描述符,監(jiān)聽上的事件。 NIO是什么就不在此文展開,這篇主要來介紹下我們要怎樣通過java NIO來構(gòu)建一個服務客戶端程序的。 0x01 涉及知識點 NIO建立一個服務端和客戶端程序主要涉及的知識點有: ...
摘要:通常來說所有的的操作都是從開始的一個類似于一個和對比我們可以在同一個中執(zhí)行讀和寫操作然而同一個僅僅支持讀或?qū)懣梢援惒降刈x寫而是阻塞的同步讀寫總是從中讀取數(shù)據(jù)或?qū)?shù)據(jù)寫入到中類型有文件操作操作操作操作使用在服務器端這些通道涵蓋了和網(wǎng)絡以及文件 Java NIO Channel 通常來說, 所有的 NIO 的 I/O 操作都是從 Channel 開始的. 一個 channel 類似于一個 ...
摘要:抽象類有一個方法用于使通道處于阻塞模式或非阻塞模式。注意抽象類的方法是由抽象類實現(xiàn)的,都是直接繼承了抽象類。大家有興趣可以看看的源碼,各種抽象類和抽象類上層的抽象類。 歷史回顧: Java NIO 概覽 Java NIO 之 Buffer(緩沖區(qū)) Java NIO 之 Channel(通道) 其他高贊文章: 面試中關(guān)于Redis的問題看這篇就夠了 一文輕松搞懂redis集群原理及搭建...
閱讀 3096·2021-11-24 10:47
閱讀 3855·2021-11-02 14:43
閱讀 2248·2021-09-26 10:15
閱讀 2305·2021-09-08 09:35
閱讀 582·2019-08-30 12:45
閱讀 2789·2019-08-29 17:04
閱讀 3223·2019-08-26 14:05
閱讀 1273·2019-08-26 12:10