一個非阻塞I/O的例子
阿新 • • 發佈:2019-01-25
為了使讀者更好地理解非阻塞I/O,本節給出了一個簡單的例子用來演示如何將非阻塞I/O應用到網路程式中。讀者可以先不必管這個例子的具體細節。因為這個例子的主要目的並不是講解非阻塞I/O的使用,而是先讓讀者對非阻塞I/O有一個籠統的感性認識。在看完這個例子後,讀者可能會有很多疑問,在本章後面的部分將會逐漸揭開這些迷團。這個例子的主要功能是訪問新浪網,並將新浪網的首頁在控制檯上輸出。
package test; import java.net.*; import java.nio.*; import java.nio.channels.*; import java.io.*; publicclass FirstNonBlockingIO { { SocketAddress remote =new InetSocketAddress("www.sina.com.cn", 80); SocketChannel channel = SocketChannel.open(remote); String request ="GET / HTTP/1.1\r\n"+"Host:www.sina.com.cn\r\n"+"Connection:close\r\n\r\n"; ByteBuffer header channel.write(header); ByteBuffer buffer = ByteBuffer.allocate(1024); WritableByteChannel out = Channels.newChannel(System.out); while (channel.read(buffer) !=-1) { buffer.flip(); out.write(buffer); buffer.clear(); } channel.close(); } } |
執行如下命令:
java test.FirstNonBlockingIO > sina.txt |
開啟sina.txt後,會看到如下的檔案內容:
HTTP/1.0200 OK Date: Sun,01 Apr 200706:53:50 GMT Server: Apache/2.0.58 (Unix) Last-Modified: Sun,01 Apr 200706:50:47 GMT Connection: close </body> </html> |
由於新浪網的主頁內容太多,因此,為了方便檢視程式執行結果,使用輸出重定向符“>”將本該輸出到控制檯的內容輸出到sina.txt檔案中。從例程7-1可以看出,主要有三點和同步I/O存在差異。
1. 連線伺服器(第013行)。使用SocketChannel類,而不是Socket類。
2. 向服務端寫資料(第018行)。 使用SocketChannel類中的write方法,而不是OutputStream.
3. 從服務端讀資料(第021行)。使用SocketChannel類中的read方法,而不是InputStream.
除了上面的三點外,在本例中還使用了緩衝區來處理輸入輸出資料。因此,通道(Channels)和緩衝區(Buffers)是學習非阻塞I/O之前必須掌握的知識。在下面的文章等將詳細講解這兩部分的內容。