为了使读者更好地理解非阻塞I/O本节给出了一个简单的例子用来演示如何将非阻塞I/O应用到网络程序中读者可以先不必管这个例子的具体细节因为这个例子的主要目的并不是讲解非阻塞I/O的使用而是先让读者对非阻塞I/O有一个笼统的感性认识在看完这个例子后读者可能会有很多疑问在本章后面的部分将会逐渐揭开这些迷团这个例子的主要功能是访问新浪网并将新浪网的首页在控制台上输出
package test;
import*;
importjavanio*;
importjavaniochannels*;
importjavaio*;
publicclassFirstNonBlockingIO
{
publicstaticvoidmain(String[]args)throwsException
{
SocketAddressremote=newInetSocketAddress();
SocketChannelchannel=SocketChannelopen(remote);
Stringrequest=GET/HTTP/\r\n+
Host:\r\n+
Connection:close\r\n\r\n;
ByteBufferheader=ByteBufferwrap(requestgetBytes());
channelwrite(header);
ByteBufferbuffer=ByteBufferallocate();
WritableByteChannelout=ChannelsnewChannel(Systemout);
while(channelread(buffer)!=)
{
bufferflip();
outwrite(buffer);
bufferclear();
}
channelclose();
}
}
测试
执行如下命令
javatestFirstNonBlockingIO>sinatxt
打开sinatxt后会看到如下的文件内容
HTTP/OK
Date:SunApr::GMT
Server:Apache/(Unix)
LastModified:SunApr::GMT
Connection:close
</body>
</html>
由于新浪网的主页内容太多因此为了方便查看程序运行结果使用输出重定向符>将本该输出到控制台的内容输出到sinatxt文件中从例程可以看出主要有三点和同步I/O存在差异
连接服务器(第行)使用SocketChannel类而不是Socket类
向服务端写数据(第行) 使用SocketChannel类中的write方法而不是OutputStream
从服务端读数据(第行)使用SocketChannel类中的read方法而不是InputStream
除了上面的三点外在本例中还使用了缓沖区来处理输入输出数据因此通道(Channels)和缓沖区(Buffers)是学习非阻塞I/O之前必须掌握的知识在下面的文章等将详细讲解这两部分的内容