Chapter 11th Non-blocking I/O

Source: Internet
Author: User
Tags rewind

Chapter 11th Non-blocking I/OAn Instance client

When the client that implements the new I/O, calls the static Factory method Socketchannel.open () to create a new Java.nio.channels.SocketChannel object. The parameter of this method is a Java.net.SocketAddress object that indicates the host and port to connect to.

For example, the following code snippet connects to a channel that points to rama.poly.edu Port 19:

SocketAddress Rama = new Inetsocketaddress ("rama.poly.edu", 19);

Socketchannel client = Socketchannel.open (Rama);

With a channel, you can write directly to the channel itself instead of writing the Bytebuffer object.

Bytebuffer buffer = bytebuffer.allocate (74);

Pass this Bytebuffer object to the Read () method of the channel. The channel fills the buffer with data read from the socket. It returns the number of bytes successfully read and stored in the buffer:

int bytesread = client.read (buffer);

This will read at least one byte, or return 1 indicates the end of the data.

Example 11-1: A channel-based Chargen client

<span style= "FONT-SIZE:18PX;" >import java.nio.*;import java.nio.channels.*;import Java.net.*;import Java.io.ioexception;public class    chargenclient {public static int default_port = 19; public static void Main (string[] args) {if (args.length = = 0) {System.out.println ("Usage:java chargenclient H       OST [Port] ");    Return    } int port;    try {port = integer.parseint (args[1]);       } catch (RuntimeException ex) {port = Default_port;      try {socketaddress address = new Inetsocketaddress (args[0], port);            Socketchannel client = Socketchannel.open (address);      Bytebuffer buffer = bytebuffer.allocate (74);            Writablebytechannel out = Channels.newchannel (System.out);        while (client.read (buffer)! =-1) {buffer.flip ();        Out.write (buffer);      Buffer.clear ();       }} catch (IOException ex) {ex.printstacktrace (); }}}</span>

This connection can be allowed in blocking or non-blocking mode, and read () returns immediately, even without any available data, in non-blocking mode. This allows the program to do other things before attempting to read. It does not have to wait for a slow network connection. To change the blocking mode, you can pass in true (blocking) or false (without blocking) to the Configureblocking () method.

Client.configureblocking (FALSE);

In nonblocking mode, read () may return 0 because it cannot read any data. So the loop needs some difference:

while (true) {

Put the code that is allowed for Each loop here, whether or not you read the data

int n = client.read (buffer);

if (n > 0) {

Buffer.flip ();

Out.write (buffer);

Buffer.clear ();

}else if (n = =-1) {

This should not happen unless the server sends a fault

Break

}

}

an instance server

Example 11-2: A non-blocking Chargen server

<span style= "FONT-SIZE:18PX;" >import java.nio.*;import java.nio.channels.*;import java.net.*;import java.util.*;import java.io.IOException;    public class Chargenserver {public static int default_port = 19;    public static void Main (string[] args) {int port;    try {port = integer.parseint (Args[0]);       } catch (RuntimeException ex) {port = Default_port;    } System.out.println ("Listening for connections on port" + port);    byte[] rotation = new BYTE[95*2];          for (Byte i = "; I <= ' ~ '; i++) {rotation[i-"] = i;        Rotation[i +--"] = i;    } Serversocketchannel Serverchannel;    Selector Selector;      try {Serverchannel = Serversocketchannel.open ();      ServerSocket ss = Serverchannel.socket ();      Inetsocketaddress address = new inetsocketaddress (port);      Ss.bind (address);      Serverchannel.configureblocking (FALSE);      selector = Selector.open (); Serverchannel.register (Selector, SELECTIONKEY.OP_ACCEPT);      } catch (IOException ex) {ex.printstacktrace ();       Return      } while (true) {try {selector.select ();        } catch (IOException ex) {ex.printstacktrace ();      Break      } set<selectionkey> Readykeys = Selector.selectedkeys ();      iterator<selectionkey> Iterator = Readykeys.iterator ();        while (Iterator.hasnext ()) {Selectionkey key = Iterator.next ();        Iterator.remove ();            try {if (key.isacceptable ()) {Serversocketchannel Server = (Serversocketchannel) key.channel ();            Socketchannel client = Server.accept ();            SYSTEM.OUT.PRINTLN ("Accepted connection from" + client);            Client.configureblocking (FALSE);                                                                    Selectionkey Key2 = Client.register (selector, Selectionkey.            Op_write);            Bytebuffer buffer = bytebuffer.allocate (74); Buffer.put (RotatiOn, 0, 72);            Buffer.put ((byte) ' \ R ');            Buffer.put ((byte) ' \ n ');            Buffer.flip ();          Key2.attach (buffer);            } else if (Key.iswritable ()) {Socketchannel client = (Socketchannel) key.channel ();            Bytebuffer buffer = (bytebuffer) key.attachment ();               if (!buffer.hasremaining ()) {//refill the buffer with the next line Buffer.rewind ();              Get the old first character int first = Buffer.get ();              Get ready-to-change the data in the buffer Buffer.rewind ();              Find the new first characters position in rotation int position = first-"+ 1;              Copy the data from rotation into the buffer buffer.put (rotation, position, 72);              Store a line break at the end of the buffer Buffer.put ((byte) ' \ R ');              Buffer.put ((byte) ' \ n '); Prepare the buffer foR writing Buffer.flip ();          } client.write (buffer);          }} catch (IOException ex) {key.cancel ();          try {Key.channel (). Close (); } catch (IOException CeX) {}}}}}</span>
buffers

The key difference between a stream and a channel is that the stream is byte-based and the channel is block-based.

Regardless of the buffer type, there is the same method to get and set the buffer to 4 key parts of the information.

Position

The next location that will be read or written in the buffer.

Public final int position ()

Public final Buffer position (int newposition)

Capacity

The maximum number of elements the buffer can hold. The capacity value is set when the buffer is created and cannot be changed thereafter.

Public final int Capacity ()

Limit

The end position of the data that can be accessed in the buffer. As long as you do not change the limit, you cannot read/write data that exceeds this location, even if the buffer has greater capacity.

public final int limit ()

Public final Buffer limit (int newlimit)

Mark

The index specified by the client in the buffer. You can set the marker to the current position by calling Mark (). Call Reset () to set the current position to the location you are marking.

The common buffer superclass provides several additional methods:

Public final Buffer Clear ()

The clear () method sets the position to 0 and sets the limit to capacity, which "empties" the buffer.

Public final Buffer Rewind ()

Sets the position to 0 without changing the limit and also allows the buffer to be re-read

Public final Buffer Flip ()

Set the limit to the current position, set to 0, and call this method when you want to empty the buffer you just filled.

Public final int remaining ()

Returns the number of elements between the current position and the limit in the buffer.

Public Final Boolean hasremaining () _

Returns true if the remaining element is greater than the 0,hasremaining () method

Creating Buffersan empty buffer is typically created by the allocation (allocate) method. The buffer of pre-populated data is created by the wrapper (wrap) method. The allocation method is typically used for input, and the wrapping method is generally used for output. DistributionThe Basic Allocate () method returns only a new buffer with a specified fixed capacity, which is an empty buffer. Bytebuffer buffer1 = bytebuffer.allocate (+);Intbuffer buffer2 = intbuffer.allocate (+);Direct Distributionthe Bytebuffer class has another Allocatedirect () method that does not create a fallback array for the buffer. PackagingIf you already have an array of data to output, you typically wrap it in a buffer instead of allocating a new buffer. byte[] data = "Some data". GetBytes ("UTF-8");Bytebuffer buffer1 = bytebuffer.wrap (data);Filling and emptyingBatch Methoddifferent buffer classes have some batch methods to populate and empty an array of corresponding elements. Bytebuffer has the put () and get () methods, which can be used with an existing byte array or emptying an array of the corresponding element type. For example: Bytebuffer has the put () and get () methods to populate and empty a bytebuffer with an existing byte array or subarray:Public Bytebuffer Get (byte[] dst,int offset,int length)Public Bytebuffer get (byte[] DST)Public Bytebuffer put (byte[] array,int offset,int length)Public Bytebuffer put (byte[] array)Data Conversionall the data in Java eventually resolves to bytes. All basic data Types--int, double, float, and so on can be written as bytes. any byte sequence of the appropriate length can be interpreted as a basic type of data. For example, any 4-byte sequence can correspond to an int or float (both, in fact, depending on how you want to read). a 8-byte sequence corresponds to a long or double. View Buffersif the Bytebuffer read from Socketchannel contains only one element of a particular base data type, then it is necessary to create a view buffer. Compression BuffersMost writable buffers support the compact () method. compresses all the remaining data in the buffer to the beginning of the buffer, freeing up more space for the element. Any data in these locations will be overwritten. The position of the buffer is set to the end of the data so that more data can be written. Copy Buffercreates a copy of the buffer to distribute the same information to two or more channels. 6 Specific types of buffers provide the duplicate () method to do the work. Shard BuffersThe Shard (slicing) buffer is a variant of replication. Shards also create a new buffer to share data with the original buffer. However, the starting position of the Shard (position 0) is the current position of the original buffer, and its maximum capacity does not exceed the limit of the source buffer. That is, a shard is a subsequence of the original buffer, and the value contains all elements from the current position to the limit. tagging and resettingChannelThe channel moves the data block of the buffer into or out of the various I/O sources. SocketchannelThe Socketchannel class can read and write TCP sockets. The data must be encoded into the Bytebuffer object to complete the read/write. Each socketchannel is associated with a peer socket object. Connectiontwo static Open () methods to create a new Socketchannel object:Public static Socketchannel open (SocketAddress remote) throws IOExceptionThis method establishes a connection that will block (that is, the method does not return until the connection is established or throws an exception). Public Static Socketchannel open () throws IOExceptionno parameter versions are not immediately connected. It creates an initial, disconnected socket that must be connected in the future with the Connect () method. ReadTo read Socketchannel, you first create a bytebuffer where the channel can store the data. Then pass this bytebuffer to the Read () method:public abstract int Read (Bytebuffer DST) throws IOException The channel fills the buffer with as much data as possible, and then returns the number of bytes put in. WriteThe socket channel provides a read-write method. To write, simply fill in a bytebuffer, wrap it around, and pass it to a write method, which then copies the data to the output and empties the buffer, which is the opposite of the read process. the basic write () method receives a buffer as a parameter:public abstract int write (Bytebuffer src) throws IOException Closepublic void Close () throws IOException public boolean IsOpen () ServersocketchannelThe Serversocketchannel class has only one purpose: to accept inbound connections. Create a server socket channeltry{Serversocketchannel Server = Serversocketchannel.open (); ServerSocket socket = Server.socket (); socketaddress address = new Inetsokcetaddress; Socket.bind (address); } catch (IOException ex) {System.err.println (".."); }processing in Java 7:try{Serversocketchannel Server = Serversocketchannel.open (); socketaddress address = new Inetsocketaddress; Server.bind (address); } catch (IOException ex) {System.err.pringln ("..."); }Accept ConnectionPublic Abstract Socketchannel accept () throws IOExceptionthe Accept () method allows you to listen to inbound connections. Can operate in blocking or non-blocking mode. blocking Modethe Accept () method waits for an inbound connection. He then accepts a connection and returns a Socketchannel object connected to the remote client. The thread was unable to do anything until the connection was established. This policy applies to simple servers that respond to every request immediately. Blocking mode is the default mode. non-blocking modeIf there is no inbound connection, the Accept () method returns null. nonblocking mode is more appropriate for servers that need to do a lot of work for each connection, so that multiple requests can be processed in parallel. Non-blocking mode is generally used in conjunction with selector, in order to pass the Configureblocking () method to False for the Serversocketchannel in non-blocking mode. Channels ClassTraditional I/O-based streams, readers, and writers can be packaged in channels or converted from channels to I/O-based streams, readers, and writers.
Asynchronous channel (JAVA7)
Java 7 introduces the Asynchronoussocketchannel and Asynchronousserversocketchannel classes.
The read/write asynchronous channel returns immediately, even before I/O is complete. The data read/written will be further processed by a future or completionhandler. The Connect () and accept () methods are also executed asynchronously and return to the future. Selectors are not used here.
Example:
SocketAddress address = new Inetsocketaddress (args[0],port);
Asynchronoussocketchannel client = Asynchronoussocketchannel.open ();
future<void> connected = Client.connect (address);

Bytebuffer buffer = bytebuffer.allocate (74);

Waiting for connection
Connected.get ();

Read from connection
future<integer> future = client.read (buffer);

Do other work ...

Waiting for read to complete ...
Future.get ();

Wrap and empty buffers
Buffer.flip ();
Writablebytechannel out = Channels.newchannel (System.out);
Out.write (buffer);
The network connection runs in parallel, while the program can do other things. When you are ready to process data from the network, it stops and waits for the data by calling Future.get (), but not before stopping.
If you do not care about the fetch order, you can generate a large number of Asynchronoussocketchannel requests and provide a completionhandler for each request, which stores the results on the backend.
Two methods were declared through the Completionhandler interface: Completed () and failed (), completed () is called if successful reading, and failed () is called when an I/O error occurs.
Socket option (JAVA7)
Starting with Java 7, Socketchannel,serversocketchannel,asynchronousserversocketchannel, Both Asynchronoussocketchannel and Datagramchannel implement the new Networkchannel interface. The main purpose of this interface is to support various TCP options.
The Channel class has 3 methods to get, set, and list the supported options:
<T> T getOption (socketoption<t> name) throws IOException
<T> networkchannel setOption (socketoption<t> name,t value) throws IOException
Set<socketoption<?>> supportedoptions ()
The Standardsocketoptions class provides the corresponding constants for the 11 options that Java can recognize.
For example:
Networkchannel channel = Socketchannel.open ();
Channel.setoption (standardsocketoptions.so_linger,240);
Ready Selection  ready choice, that is, can choose to read and write without blocking the socket.
to complete the ready selection, register the different channels to a selector object. Each channel is assigned a selectionkey. Then the program can ask the Selector object, those channels are ready to do what you want to do without blocking, you can request the Selector object to return the corresponding key collection.
Selector class
Creates a new selector:
public static Selector open () throws IOException
adds a channel to the selector. The register () method is declared in the Selectablechannel class. By passing the selector to a registration method of the channel, you can register the channel with the selector:
Public final Selectionkey register (Selector Sel,int Ops) throws Closedchannelexception
Public Final Selectionkey reigster (Selector sel,int ops, Object att) throws Closedchannelexception
The first parameter is the selector to which the channel is registered. The
second parameter is a named constant in the Selectionkey class that identifies the operation registered by the channel. The
third parameter is optional, which is an attachment to the key.

There are three ways to select a ready channel. They differ in the time it takes to find a ready channel to wait.
public abstract int Selectnow () throws IOException
Complete the non-blocking selection. If a connection is not currently ready to be processed, it returns immediately.
public abstract int Select () throws IOException
Blocking. Wait until at least one of the registered channels is ready to be processed before returning.
public abstract int Select (long timeout) throws IOException
Blocked, wait no more than timeout milliseconds before returning 0.

When a channel is ready for processing, you can use the Selectedkeys () method to get the Ready channel:
Public abstract set<selectionkey> Selectedkeys ()
When iterating over the returned collection, the individual selectionkey are processed in turn.
When you are ready to shut down the server or you no longer need the selector, you should turn it off:
public abstract void Close () throws IOException
Frees all resources associated with the selector.
Selectionkey class
The Selectionkey object is equivalent to a pointer to a channel.
Use the Channel () method to obtain this passage:
Public abstract Selectablechannel channel ()
If you end up using a connection, you revoke the registration of its Selectionkey object so that the selector does not waste resources to query whether it is ready. Call the Cancel () method of this key to unregister:
public abstract void Cancel ()

Chapter 11th Non-blocking I/O

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.