理解Buffer的limit和capacity这两个值之间的区别是十分重要的。Capacity是某个Buffer对象所能包含的项数的最大值。Limit是在0到capacity之间的一个值,它表示一个限度,可以使用limit或者flip方法来设置它。我们来看下面的例子: // Sample of using flip buffer.position(5); buffer.flip(); while (buffer.hasRemaining()) { int i = buffer.get(); System.out.println("i="+i); }
另一个重要的Buffer类的方法是clear,它将设置position为0并设置limit为Buffer的容量值。基本上,clear方法消除这之前flip(或limit)方法产生的影响。考虑下例: // Sample of using clear buffer.clear(); while (buffer.hasRemaining()) { int i = buffer.get(); System.out.println("i="+i); }
服务器端非阻塞(Server Nonblocking) 我以前的部分介绍过的实体都有与其相当的Java实体。客户端和服务器端是两个Java应用程序。套接字通道是SocketChannel类的实例,这个类答应通过网络传送数据。它们能被Java程序员看作是一个新的套接字。SocketChannel类被定义在java.nio.channel包中。 选择器是一个Selector类的对象。该类的每个实例均能监视更多的套接字通道,进而建立更多的连接。当一些有意义的事发生在通道上(如客户端试图连接服务器端或进行读/写操作),选择器便会通知应用程序处理请求。选择器会创建一个要害字,这个要害字是SelectionKey类的一个实例。每个要害字都保存着应用程序的标识及请求的类型。其中,请求的类型可以是如下之一: ●尝试连接(客户端) ●尝试连接(服务器端) ●读取操作 ●写入操作 一个通用的实现非阻塞服务器的算法如下: create SocketChannel; create Selector associate the SocketChannel to the Selector for(;;) { waiting events from the Selector; event arrived; create keys; for each key created by Selector { check the type of request; isAcceptable: get the client SocketChannel; associate that SocketChannel to the Selector; record it for read/write Operations continue; isReadable: get the client SocketChannel; read from the socket; continue; isWriteable: get the client SocketChannel; write on the socket; continue; } }