這一篇要說明的是,如何使用 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。
NIO2 (1) --- TCP (blocking),布布扣,bubuko.com
时间: 2024-12-29 23:22:22