J2SE version 1.4 introduces a nonblocking socket (sockets), which allows sockets to be used in network communication applications and in processes that do not obstruct. This article describes in detail what is a non-blocking socket (nonblocking sockets) and its working principle and use.
From Java 1.4, programmers can use a new set of APIs for I/O operations. This is the result of the JSR 51 project, which allows programmers to use JSR 51 since the January 2000 beta version of Java 1.4. Some very important new technologies have been added in Java 1.4 to handle high performance read/write operations on files and sockets, regular expressions, decoding/coded character sets, memory mappings, and file locking. In this article, we will discuss a special new api――new I/O api:nonblocking sockets.
Non-blocking sockets allow an input/output operation on a channel without blocking the process of the channel. In this article I will discuss the techniques for asynchronous high-performance read/write operations and flip up and down design and development of an interface based application.
Java developers may ask, why introduce a new technology to deal with sockets? What are the problems with the Java 1.3.x sockets? Assume that the server side accepts connections from different clients. Also, assume that the client can support multiple requests to handle synchronization. With Java 1.3.x, there are two different options for developing such a server-side:
Implement multithreaded services to process threads for each connected user.
Use external third party modules.
Both approaches can be implemented, but the first approach-the entire thread management scenario, including related concurrency and conflict issues-needs to be handled by programmers. The second scenario may be more expensive and allow applications to rely on "NON-JDK" external modules. Depending on the non blocking socket, you can implement a barrier-free service without directly managing threads or using external modules.
Buffer
Before we consider a java.nio.Buffer socket, we have to spend some time on a new Java 1.4 class: the "Top". A buffer instance is only a limited container for the raw data. It is said to be limited because it can only contain a limited number of bytes; in other words, it is not a container like a vector or a ArrayList, which theoretically has no limits. In addition, a buffer instance can contain only basic data types that belong to Java. For example: Int,char,double,boolean, et cetera.
The buffer class is an abstract class that has 7 subclasses corresponding to seven basic data types:
Bytebuffer
Charbuffer
DoubleBuffer
Floatbuffer
Intbuffer
Longbuffer
Shortbuffer
In a non-blocking socket programming environment where all new I/O systems work, it is extremely important to solve how the buffer objects work. This is because the new socket channel uses a buffer object to transmit data over the network.
You can use the following static method (i.e. class method) to create a new buffer instance: Allocate,allocatedirect,wrap. In the following example, three buffer objects are instantiated in three different ways.
ByteBuffer buffer1 = ByteBuffer.allocate(1024);
ByteBuffer buffer2 = ByteBuffer.allocateDirect(1024);
ByteBuffer buffer3 = ByteBuffer.wrap(new String("hello").getBytes());
The first two lines of this code create two Bytebuffer objects, all of which contain 1024 bytes. Both the allocate and Allocatedirect methods do the same work, but the second method uses the operating system directly to allocate buffer. Thus it will provide faster access speed. Unfortunately, not all virtual machines support this method of direct allocation. The third line uses the Wrap method. It creates a Bytebuffer object that contains a byte that consists of the string "Hello".
The function of a buffer object is more or less similar to that of a stream. "Current Position" is an extremely important concept that calculates the appropriate location for the buffer object you are going to work with. At any time, a buffer object has a current position pointing to an item. After that, each read or write operation automatically points the current position to the next item in the buffer.
You can write some data into the buffer by using the Put method:
// Writing on a buffer
IntBuffer buffer = IntBuffer.allocate(10);
for (int i=0; i < buffer.capacity(); i++) {
buffer.put(i);
}
This code creates a buffer containing 10 integer values, and then puts the numbers 0 through 9 into the buffer. And as you can see, I used the capacity method to get the capacity of the buffer.