1. 程式人生 > >一個非阻塞I/O的例子

一個非阻塞I/O的例子

為了使讀者更好地理解非阻塞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
{
    
publicstaticvoid main(String[] args) throws Exception
    {
        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 
= ByteBuffer.wrap(request.getBytes());
        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之前必須掌握的知識。在下面的文章等將詳細講解這兩部分的內容。