Java NiO socket

Source: Internet
Author: User

March 12, 2002

The Java technology platform should have provided non-blocking I/O mechanisms for a long time. Fortunately, Merlin (JDK 1.4) has a magic wand that applies in almost every scenario, and the blocking state of the blocked I/O is exactly what the magician is doing. Software engineers Aruna kalagnanam and Balu g introduced Merlin's new I/O package-java. niO (NIO)-This non-blocking feature, and uses a socket programming example to show you what NiO can do. Click
Discussion, In
The Forum will share your experiences with the author and other readers about this article.

The server's ability to process a large number of client requests within a reasonable period of time depends on the efficiency of the server's use of the I/O Stream. At the same time, servers that provide services to hundreds of clients must be able to concurrently use the I/O service. The Java platform does not support non-blocking I/O calls until JDK 1.4 (Merlin. For a server written in Java, the ratio of the thread to the client is almost the same, which is vulnerable to a large number of thread overhead. The result is that both performance problems and scalability are caused.

To solve this problem, the latest release of the Java platform introduces a new group of classes. Merlin's Java. Nio package is full of skills to solve thread overhead problems. The most important thing in the package is the new
SelectableChannel
Class andSelectorClass.
Channel)It is a communication method between the client and the server.Selector)Similar to Windows message loop, it captures various events from different clients and distributes them to corresponding event handlers. In this article, we will show you how these two classes work together to create a non-blocking I/O Mechanism for the Java platform.

I/O programming before Merlin

We will start from the basic server-socket (server-socket) program before Merlin. InServerSocketImportant Functions of the class are as follows:

  • Accept incoming connections
  • Read requests from clients
  • Provide services for requests

Let's take a look at each of the above steps. We use code snippets to describe them. First, we create a newServerSocket:

ServerSocket s = new ServerSocket();

Next, we need to accept incoming calls. Here, callaccept()You should be able to complete the task, but there is a small trap:

Socket conn = s.accept( );

Pairaccept()Until the server socket accepts a client request for connection. Once a connection is established, the server uses
LineNumberReaderRead client requests. Because
LineNumberReaderData is read in batches only when the buffer is full, so this call is blocked during reading. The following snippet shows
LineNumberReader(Blocking, etc ).

InputStream in = conn.getInputStream();InputStreamReader rdr = new InputStreamReader(in);LineNumberReader lnr = new LineNumberReader(rdr);Request req = new Request();while (!req.isComplete() ){   String s = lnr.readLine();   req.addLine(s);}

InputStream.read()Is another way to read data. Unfortunately,
readThe method must be blocked until the data is available,
write
The same is true ,.

Figure 1 depicts a typical server process. A black line indicates a blocking operation.

Figure 1. Typical servers at work

Before JDK 1.4, free use of threads is the most typical way to handle blocking problems. However, this solution produces its own problem-thread overhead, which affects both performance and scalability. However, with the advent of Merlin and Java. Nio packages, everything has changed.

In the following sections, we will examine the basic idea of Java. NiO, and then apply some of the knowledge we have learned to modify the server-socket example described above.



Back to Top

Reactor Pattern)

The foundation of NiO design is the design mode of reactors. Server Applications in distributed systems must process multiple clients that send service requests to them. However, before calling a specific service, the server application must allocate and distribute each incoming request to the corresponding service provider. The reactor mode is suitable for this function. It allows event-driven applications to distribute and distribute service requests concurrently from one or more clients to the application.

Core functions of the reactor model

  • Multiplexing of events
  • Distribute events to corresponding event handlers

The reactor pattern is very similar to the observer pattern in this respect: When a subject changes, all dependent bodies are notified. However, the observer mode is associated with a single event source, while the reactor mode is associated with multiple event sources.

See
For more information about the reactor mode, see references.



Back to Top

Channels and selectors

NIO's non-blocking I/O mechanism is centered aroundSelectorAndChannelBuilt.ChannelClass indicates a communication mechanism between the server and the client. Consistent with the reactor mode,
SelectorClass isChannel.
SelectorClass is used to distribute incoming client requests to multiple channels and distribute them to their respective request handlers.

We will take a closer lookChannelClass and
Selector
And how the two classes work together to create non-blocking I/O implementations.

What do channels do?

A channel represents a connection to an object (for example, a hardware device, file, network socket, or program component that can perform one or more different I/O operations (for example, read or write). The NiO channel can be closed and interrupted asynchronously. Therefore, if a thread blocks the I/O operations of a channel, the other thread can close the channel. Similarly, if a thread is blocked in the I/O operation of a channel, the other thread can interrupt the blocking thread.

Figure 2. java. NiO. Channels class hierarchy

As shown in figure 2, there are many Channel interfaces in the Java. NiO. Channels package. We are mainly concerned aboutjava.nio.channels.SocketChannelInterfaces and
java.nio.channels.ServerSocketChannelInterface. These two interfaces can be used to replace
java.net.SocketAndjava.net.ServerSocket. Although we will certainly focus on using channels in a non-blocking manner, the channel can be used in blocking or non-blocking mode.

Create a non-blocking Channel

To implement basic non-blocking Socket read and write operations, we need to process two new classes. They are from the java.net package.InetSocketAddressClass, which specifies the connection location and from the java. NiO. Channels package
SocketChannelClass, which performs the actual read and write operations.

The code snippets in this section show a modified, non-blocking method to create a basic server-socket program. Note the changes between these code samples and the code used in the first example, starting with adding two new classes:

String host = ......;   InetSocketAddress socketAddress = new InetSocketAddress(host, 80); SocketChannel channel = SocketChannel.open();   channel.connect(socketAddress);

Buffer role

BufferIs an abstract class that contains specific basic data types. Essentially, it is a package that wraps an array of fixed sizes with the getter/setter method. These getter/setter methods allow access to the buffer content.
BufferThe class has many subclasses, as shown below:

  • ByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

ByteBufferIs the only class that supports reading and writing other types, because other classes are specific to types. Once connected, you can use
ByteBufferThe object reads data from or writes data to the channel. See
References
ByteBuffer.

To make the channel non-blocking, we callconfigureBlockingMethod(false), As shown below:

channel.configureBlockingMethod(false);

In blocking mode, the thread blocks reading or writing until the read or write operations are complete. If the data has not completely reached the socket at the time of reading, the thread will block the reading operation until the data is available.

In non-blocking mode, the thread reads available data (no matter how much) and then returns to execute other tasks. If true is passedconfigureBlockingMethod()In
SocketThe behavior for blocking reading or writing is the same. The only major difference is that these blocked reads and writes can be interrupted by other threads.

IndependentChannelCreating non-blocking I/O implementations is not enough. To implement non-blocking I/O,
ChannelThe class must beSelectorClass.

What do selector do?

In the reactor mode,SelectorClass
Reactor
Role.SelectorFor multiple
SelectableChannels. Each
ChannelDirectionSelectorRegister an event. When the event arrives from the client,
SelectorMultiple channels are used to distribute these events to the corresponding
Channel.

CreateSelectorThe simplest way is to use
open()
Method:

Selector selector = Selector.open();

Channel encounter Selector

EachChannelYou must first create a connection. The following code is called
ServerOfServerSocketChannelAnd bind it to the local port:

ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);InetAddress ia = InetAddress.getLocalHost();InetSocketAddress isa = new InetSocketAddress(ia, port );serverChannel.socket().bind(isa);

EachChannelYou must continue
SelectorRegister.ChannelThe event to be handled should be registered based on it. For example
ChannelYou should register as follows:

SelectionKey acceptKey =     channel.register( selector,SelectionKey.OP_ACCEPT);

ChannelDirectionSelectorFor registration
SelectionKeyObject Representation. Meet one of the following three conditions,
KeyIt becomes invalid:

  • ChannelDisabled.
  • SelectorDisabled.
  • By callingKeyOfcancel()Method
    KeyCanceled.

SelectorInselect()The call is blocked. Then, it starts to wait until a new connection is established, or another thread wakes it up, or another thread interrupts the original blocked thread.

Registration Server

ServerIsSelectorRegister to accept all incoming connections
ServerSocketChannel, As shown below:

SelectionKey acceptKey = serverChannel.register(sel, SelectionKey.OP_ACCEPT);   while (acceptKey.selector().select() > 0 ){     ......

ServerAfter registration, a set of keywords are processed iteratively based on the type of each key. After a keyword is processed, it is removed from the ready keys list, as shown below:

Set readyKeys = sel.selectedKeys();    Iterator it = readyKeys.iterator();while (it.hasNext()) {SelectionKey key = (SelectionKey)it.next();  it.remove();  ....  ....  .... }

If the keyword is acceptable (acceptable), accept the connection and register the channel to accept more events (for example, read or write operations ). If the keyword is readable or writable, the server instructs you that it is ready to read and write local data:

SocketChannel socket;if (key.isAcceptable()) {    System.out.println("Acceptable Key");    ServerSocketChannel ssc = (ServerSocketChannel) key.channel();    socket = (SocketChannel) ssc.accept();    socket.configureBlocking(false);    SelectionKey another =       socket.register(sel,SelectionKey.OP_READ|SelectionKey.OP_WRITE);}if (key.isReadable()) {    System.out.println("Readable Key");    String ret = readMessage(key);    if (ret.length() > 0) {      writeMessage(socket,ret);    }      }if (key.isWritable()) {    System.out.println("Writable Key");    String ret = readMessage(key);    socket = (SocketChannel)key.channel();       if (result.length() > 0 ) {      writeMessage(socket,ret);    }    }


Back to Top

Why? alimail-non-blocking server socket is quick!

The last part of the introduction to non-blocking I/O in JDK 1.4 is left to you: Run this example.

In this simple non-blocking server-socket example, the server reads the file name sent from the client, displays the content of the file, and then writes the content back to the client.

Here is what you need to do to run this example:

  1. Install JDK 1.4 (see
    References ).
  2. Set
    Copy the source code file to your directory.
  3. Compile and run the server,java NonBlockingServer.
  4. Compile and run the client,java Client.
  5. Enter the name of a text file or Java file in the directory where the class file is located.
  6. The server will read the file and send its content to the client.
  7. The client prints the data received from the server. (BecauseByteBufferSo only 1024 bytes are read .)
  8. Enter the quit or shutdown command to close the client.



Back to Top

Conclusion

Merlin's new I/O package covers a wide range. Merlin's new non-blocking I/O implementation has two main advantages: the thread is no longer blocked during reading or writing, andSelectorIt can process multiple connections, greatly reducing the overhead of server applications.

We have already focused on the two advantages of the new java. Nio package. We hope that you will apply the knowledge learned here to your actual application development work.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.