在Java NIO體系中,SocketChannel是用於TCP網絡鏈接的套接字接口,至關於Java網絡編程中的Socket套接字接口。建立SocketChannel主要有兩種方式,以下:編程
打開一個SocketChannel能夠這樣操做:服務器
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
關閉一個SocketChannel只須要調用他的close方法,以下:網絡
socketChannel.close();
從一個SocketChannel鏈接中讀取數據,能夠經過read()方法,以下:異步
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = socketChannel.read(buf);
首先須要開闢一個Buffer。從SocketChannel中讀取的數據將放到Buffer中。socket
接下來就是調用SocketChannel的read()方法.這個read()會把通道中的數據讀到Buffer中。read()方法的返回值是一個int數據,表明這次有多少字節的數據被寫入了Buffer中。若是返回的是-1,那麼意味着通道內的數據已經讀取完畢,到底了(連接關閉)。spa
向SocketChannel中寫入數據是經過write()方法,write也須要一個Buffer做爲參數。下面看一下具體的示例:code
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); }
仔細觀察代碼,這裏咱們把write()的調用放在了while循環中。這是由於咱們沒法保證在write的時候實際寫入了多少字節的數據,所以咱們經過一個循環操做,不斷把Buffer中數據寫入到SocketChannel中知道Buffer中的數據所有寫入爲止。接口
咱們能夠吧SocketChannel設置爲non-blocking(非阻塞)模式。這樣的話在調用connect(), read(), write()時都是異步的。ip
若是咱們設置了一個SocketChannel是非阻塞的,那麼調用connect()後,方法會在連接創建前就直接返回。爲了檢查當前連接是否創建成功,咱們能夠調用finishConnect(),以下:get
socketChannel.configureBlocking(false); socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); while(! socketChannel.finishConnect() ){ //wait, or do something else... }
在非阻塞模式下,調用write()方法不能確保方法返回後寫入操做必定獲得了執行。所以咱們須要把write()調用放到循環內。這和前面在講write()時是同樣的,此處就不在代碼演示。
在非阻塞模式下,調用read()方法也不能確保方法返回後,確實讀到了數據。所以咱們須要本身檢查的整型返回值,這個返回值會告訴咱們實際讀取了多少字節的數據。
SocketChannel的非阻塞模式能夠和Selector很好的協同工做。把一個活多個SocketChannel註冊到一個Selector後,咱們能夠經過Selector指導哪些channels通道是處於可讀,可寫等等狀態的。後續咱們會再詳細闡述若是聯合使用Selector與SocketChannel。