非阻塞套接字(Nonblocking Sockets) 概述

来源:互联网 发布:unity3d屠夫钩子 编辑:程序博客网 时间:2024/05/22 11:35

Buffer
在我们考虑非阻塞套接字以前,不得不花费一些字句在一个新的Java 1.4的类:java.nio.Buffer上。一个Buffer实例只是原始数据的一个有限的容器。称其有限是因为它只能包含有限数量的字节;换句话说,它不是一个像Vector或是ArrayList一样的容器,后两者从理论上说是没有限度的。另外,一个Buffer实例仅能包含属于Java的基本数据类型。例如:int,char,double,Boolean,等等。

Buffer类是一个抽象类,它有7个子类分别对应于七种基本的数据类型:
●ByteBuffer
●CharBuffer
●DoubleBuffer
●FloatBuffer
●IntBuffer
●LongBuffer
●ShortBuffer

在非阻塞化套接字编程中,通常所有新 I/O系统能工作的环境中,解决Buffer对象如何工作是关键。这是因为新套接字通道使用Buffer对象通过网络来传送数据。
你可以使用以下静态方法(即类方法)来创建一个新的Buffer实例:allocate,allocateDirect,wrap。在下面的例子中,三个Buffer对象将用三种不同的方法来实例化。

ByteBuffer buffer1 = ByteBuffer.allocate(1024);
ByteBuffer buffer2 = ByteBuffer.allocateDirect(1024);
ByteBuffer buffer3 = ByteBuffer.wrap(new String("hello").getBytes());

这段代码的前两行创建了两个ByteBuffer对象,它们都包含1024个字节。allocate和allocateDirect方法都做了相同的工作,
不同的是第二个方法直接使用操作系统来分配Buffer。因而它将提供更快的访问速度。不幸的是,
并非所有的虚拟机都支持这种直接分配的方法。
第三行使用wrap方法。它创建了一个ByteBuffer对象,包含的字节由字符串“hello”组成。

Buffer对象的作用或多或少的与流的作用相似。“当前位置(current position)”是一个极其重要的概念,
它计算出你将要处理的Buffer对象的适当的位置。在任何时候,一个Buffer对象都有一个当前位置指向某一项。之后,每一次读或写操作都会自动的将当前位置指向Buffer中的下一项。
你可以用put方法写入一些数据到Buffer中:
// Writing on a buffer
IntBuffer buffer = IntBuffer.allocate(10);
  for (int i=0; i < buffer.capacity(); i++) {
  buffer.put(i);
}



这段代码创建了一个包含10个整型值的Buffer,然后将数字0到9放入到Buffer中。同时你可以看到,我使用了capacity方法来获得Buffer的容量。
要想读取Buffer的内容,你可以用如下方法来处理:

// Reading from a buffer
buffer.position(0);
while (buffer.hasRemaining()) {
  int i = buffer.get();
  System.out.println("i="+i);
}


调用position方法,你能设置当前位置为0;即Bufferr的起始位置。当在当前位置和limit值之间有元素时,hasRemaining方法返回true;直到超出这个范围,此方法将返回flase。while循环中的代码调用get方法读取各项,并同时显示在控制台上。

理解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);
}


当前位置被position方法设置成5。Flip方法进行如下操作:先将设置limit为当前位置的值,即5;然后再设置当前位置的值为0。因此,此后的while循环就只能扫描到前5个元素了,因为flip方法设置了新的limit值,即为5。从而,数字0,1,2,3,4将被显示出来。

另一个重要的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);
}


这段代码将显示数字0到9,而与Buffer的当前位置和limit值无关。

原创粉丝点击