Java NIO 中的 SocketChannel 是一個鏈接到 TCP 網絡套接字的通道。能夠經過如下 2 種方式建立 SocketChannel:java
下面是 SocketChannel 的打開方式:編程
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
當用完 SocketChannel 以後調用 SocketChannel.close() 關閉 SocketChannel:服務器
SocketChannel.close();
要從 SocketChannel 中讀取數據,調用一個 read() 的方法之一。如下是例子:網絡
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
首先,分配一個 Buffer。從 SocketChannel 讀取到的數據將會放到這個 Buffer 中。併發
而後,調用 SocketChannel.read()。該方法將數據從 SocketChannel 讀到 Buffer 中。read() 方法返回的 int 值表示讀了多少字節進 Buffer 裏。若是返回的是 -1,表示已經讀到了流的末尾(鏈接關閉了)。異步
寫數據到 SocketChannel 用的是 SocketChannel.write() 方法,該方法以一個 Buffer 做爲參數。示例以下:socket
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() 方法的調用是在一個 while 循環中的。write() 方法沒法保證能寫多少字節到 SocketChannel。因此,咱們重複調用 write() 直到 Buffer 沒有要寫的字節爲止。code
能夠設置 SocketChannel 爲非阻塞模式(non-blocking mode).設置以後,就能夠在異步模式下調用 connect(), read() 和 write() 了。教程
(1) connect()ip
若是 SocketChannel 在非阻塞模式下,此時調用 connect() ,該方法可能在鏈接創建以前就返回了。爲了肯定鏈接是否創建,能夠調用 finishConnect() 的方法。像這樣:
socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); while(! socketChannel.finishConnect() ){ //wait, or do something else... }
(2) write()
非阻塞模式下,write() 方法在還沒有寫出任何內容時可能就返回了。因此須要在循環中調用 write()。前面已經有例子了,這裏就不贅述了。
(3) read()
非阻塞模式下,read() 方法在還沒有讀取到任何數據時可能就返回了。因此須要關注它的 int 返回值,它會告訴你讀取了多少字節。
非阻塞模式與選擇器搭配會工做的更好,經過將一或多個 SocketChannel 註冊到 Selector,能夠詢問選擇器哪一個通道已經準備好了讀取,寫入等。Selector 與 SocketChannel 的搭配使用會在後面詳講。
轉載自併發編程網 – ifeve.com,本文連接地址: Java NIO系列教程(八) SocketChannel