標籤:style blog http color java 使用 os io
java NIO 第一彈----概覽
摘要:
Non-blocking I/O (usually called NIO, and sometimes called "New I/O") is a collection of Java programming language APIs that offer features for intensive I/Ooperations. It was introduced with the J2SE 1.4 release of Java by Sun Microsystems to complement an existing standard I/O. NIO was developed under the Java Community Process as JSR 51.[1]
大意:非阻塞I/O(通常叫做NIO,有時也叫新的I/O),是一組提供了加強版I/O操作特性的java api。在java1.4時由sun公司引入。
本系列主要著眼於網路部分,對本地檔案操作沒有涉及。接下來先看一段代碼,展示了最簡單Echo服務端。
程式碼範例
1 ByteBuffer bb = ByteBuffer.allocate(1024); 2 /**建立選取器*/ 3 Selector selector = Selector.open(); 4 /**開啟一個服務端通道*/ 5 ServerSocketChannel ssc = ServerSocketChannel.open(); 6 /**設定為非阻塞*/ 7 ssc.configureBlocking(false); 8 /**從通道中拿到服務端socket*/ 9 ServerSocket ss = ssc.socket();10 /**綁定一個連接埠*/11 InetSocketAddress addr = new InetSocketAddress(1234);12 ss.bind(addr);13 /**註冊感興趣事件,服務端通道只能註冊接受事件*/14 ssc.register(selector, SelectionKey.OP_ACCEPT);15 String receivedMsg = "";16 /**主迴圈*/17 while(true){18 int num = selector.select();19 System.out.println(num+"個事件發生。。。");20 Set<SelectionKey> selectedKeys = selector.selectedKeys();21 Iterator<SelectionKey> it = selectedKeys.iterator();22 23 /**迴圈處理每個通道事件*/24 while(it.hasNext()){25 SelectionKey key = it.next();26 it.remove();27 if(key.readyOps() == SelectionKey.OP_ACCEPT){28 System.out.println("新串連建立事件");29 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();30 SocketChannel sc = serverSocketChannel.accept();31 sc.configureBlocking(false);32 sc.register(selector, SelectionKey.OP_READ);33 }else if((key.readyOps()&SelectionKey.OP_READ) == SelectionKey.OP_READ){34 System.out.println("讀事件");35 SocketChannel sc = (SocketChannel) key.channel();36 sc.read(bb);37 receivedMsg = new String(bb.array(),0,bb.position());38 bb.clear();39 sc.register(selector, SelectionKey.OP_WRITE);40 }else if(key.readyOps() == SelectionKey.OP_WRITE){41 System.out.println("寫資料");42 SocketChannel sc = (SocketChannel) key.channel();43 sc.write(ByteBuffer.wrap(receivedMsg.getBytes()));44 /**沒有cancel就會一直迴圈進入此處,因為只要通道不阻塞會一直有寫事件,所以使用完需要取消*/45 key.cancel();46 }else{47 System.out.println("other event");48 }49 }50 }
此處代碼是一個將收到的資訊發回去的服務端代碼,給出了使用nio寫服務端的一般流程。
此處可以先有個概念和總體認識,接下來會對涉及到的重要的類進行介紹,歡迎批評指正,大家討論進步。
註:本例沒有處理IOException,實際代碼要處理,不然一個用戶端強行關閉socket就會使服務端掛掉。