首页 > 代码库 > NIO2 (1) --- TCP (blocking)
NIO2 (1) --- TCP (blocking)
這一篇要說明的是,如何使用 JDK 7 推出的 NIO 2 進行 TCP 程式開發,底下的類別圖只是其中較重要的部份,要詳細了解各類別關係,及各類別的 method,請查閱 API Documents。
NIO 2 同時提供 blocking 和 non-blocking 的模式,blocking 模式的程式因為會在接收資料時程式暫停,直到完整收完資料才又繼續執行,程式邏輯會是循序的; non-blocking 模式並不會停在接收資料的那一行程式上,而是繼續執行,至於資料傳入時,通常就由另一個執行緒接收並處理,所以,non-blocking 程式會寫成多執行緒,邏輯也會複雜許多,好處是效率會比較好。底下先來看一下個 blocking 程式,很簡單的一個 echo sever。
1 package idv.steven.nio2; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.net.StandardSocketOptions; 6 import java.nio.ByteBuffer; 7 import java.nio.channels.ServerSocketChannel; 8 import java.nio.channels.SocketChannel; 9 10 public class EchoServer { 11 12 public static void main(String[] args) { 13 final int DEFAULT_PORT = 5555; 14 final String IP = "127.0.0.1"; 15 ByteBuffer buffer = ByteBuffer.allocateDirect(1024); 16 17 //create a new server socket channel 18 try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) { 19 //continue if it was successfully created 20 if (serverSocketChannel.isOpen()) { 21 //set the blocking mode 22 serverSocketChannel.configureBlocking(true); 23 //set some options 24 serverSocketChannel.setOption(StandardSocketOptions.SO_RCVBUF, 4 * 1024); 25 serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true); 26 //bind the server socket channel to local address 27 serverSocketChannel.bind(new InetSocketAddress(IP, DEFAULT_PORT)); 28 //display a waiting message while ... waiting clients 29 System.out.println("Waiting for connections ..."); 30 //wait for incoming connections 31 while(true){ 32 try (SocketChannel socketChannel = serverSocketChannel.accept()) { 33 System.out.println("Incoming connection from: " + 34 socketChannel.getRemoteAddress()); 35 //transmitting data 36 while (socketChannel.read(buffer) != -1) { 37 buffer.flip(); 38 socketChannel.write(buffer); 39 if (buffer.hasRemaining()) { 40 buffer.compact(); 41 } else { 42 buffer.clear(); 43 } 44 } 45 } 46 catch (IOException ex) { 47 48 } 49 } 50 } else { 51 System.out.println("The server socket channel cannot be opened!"); 52 } 53 } 54 catch (IOException ex) { 55 System.err.println(ex); 56 } 57 } 58 }
現在來解釋一下上面的程式:
- Line 15: allocate 一塊記憶體,作為接收資料之用。
- Line 18: 開啟一個 channel 作為接收資料之用,但此時尚未真正將服務 bind 到指定的 IP 和 port 上。
- Line 20: 檢查是否確實開啟成功。
- Line 22: 設定這個 TCP 服務為 blocking 模式。
- Line 25: 這個設定在 multicast 才有用,在 TCP 其實可以不用設定。
- Line 27: 到這裡,服務才真的 bind 到網路上。
- Line 32: 程式會停在這,等待 request 進來。
- Line 36~44: 將收到的資料放到 buffer。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。