通道表示到實體(如硬件設備、文件、網絡套接字或程序組件)的開放鏈接,該實體可以執行一個或多個不一樣的I/O操做,例如讀取或寫入java
SeekableByteChannel
。它在其文件中有一個當前的position,能夠是查詢position,也能夠是修改的position(long)。文件自己包含一個可變長度的字節序列,能夠讀取和寫入,而且能夠查詢當前的size。當寫入的字節超過當前大小時,文件大小會增長;當文件truncated時,文件大小會減少。文件還可能具備一些關聯的元數據,例如訪問權限、內容類型和上次修改時間;此類不定義元數據訪問的方法。
open
方法建立套接字通道。沒法爲任意的、預先存在的套接字建立通道。新建立的套接字通道已打開,但還沒有鏈接。試圖在未鏈接的通道上調用I/O操做將致使引起NotYetConnectedException
。套接字通道能夠經過調用其connect
方法進行鏈接;一旦鏈接,套接字通道將保持鏈接,直到關閉。套接字通道是否鏈接能夠經過調用其isConnected
方法來肯定
Selector
是SelectableChannel
對象的多路複用選擇器open
方法來建立選擇器,該方法將使用系統默認的java.nio.channels.spi.SelectorProvider
選擇器來建立新的選擇器。還能夠經過調用自定義選擇器java.nio.channels.spi.SelectorProvider.openSelector
方法來建立選擇器。選擇器保持打開狀態,直到經過其close
方法關閉爲止SelectableChannel
註冊Selector
,並選擇感興趣的SelectionKey
。Selector
維護三組SelectionKey
:網絡
Channel
註冊的全部key
。此集合由keys()
方法返回SelectionKey
的Channel
已準備好能夠操做的key的集合。此集合由selectedKeys()
方法返回。selected-key set
始終是ket set
的子集Channel
還沒有註銷的鍵集。此集合不能直接訪問。cancelled-key set
始終是ket set
的子集ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.register(selector, SelectionKey.OP_ACCEPT);
select
的時候,這個Key還在,並且刪除須要用key的iterator
進行刪除,不然將會拋出異常(Java SE基礎知識,容器刪除元素後容器大小變化形成)public class Server { public static void main(String[] args) throws IOException { ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress("127.0.0.1", 8888)); ssc.configureBlocking(false); System.out.println("server started, listening on :" + ssc.getLocalAddress()); Selector selector = Selector.open(); ssc.register(selector, SelectionKey.OP_ACCEPT); while(true) { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); Iterator<SelectionKey> it = keys.iterator(); while(it.hasNext()) { SelectionKey key = it.next(); it.remove(); handle(key); } } } private static void handle(SelectionKey key) { if(key.isAcceptable()) { try { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); //new Client // //String hostIP = ((InetSocketAddress)sc.getRemoteAddress()).getHostString(); /* log.info("client " + hostIP + " trying to connect"); for(int i=0; i<clients.size(); i++) { String clientHostIP = clients.get(i).clientAddress.getHostString(); if(hostIP.equals(clientHostIP)) { log.info("this client has already connected! is he alvie " + clients.get(i).live); sc.close(); return; } }*/ sc.register(key.selector(), SelectionKey.OP_READ ); } catch (IOException e) { e.printStackTrace(); } finally { } } else if (key.isReadable()) { //flip SocketChannel sc = null; try { sc = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(512); buffer.clear(); int len = sc.read(buffer); if(len != -1) { System.out.println(new String(buffer.array(), 0, len)); } ByteBuffer bufferToWrite = ByteBuffer.wrap("HelloClient".getBytes()); sc.write(bufferToWrite); } catch (IOException e) { e.printStackTrace(); } finally { if(sc != null) { try { sc.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }