AsynchronousSocketChannel

java.nio.channels.AsynchronousSocketChannel Example

This article introduces the AsynchronousSocketChannel and its basic usage. This class is available since Java SE 7 as part of Java NIO 2 file API. This article’s example shows the socket channel client sending messages to an AsynchronousServerSocketChannel server – in a client/server setup.

The example in this article is compiled and run in Windows OS environment. Note that Java SE 7 is required to run the code.
 
 
 
 

1. Introduction

AsynchronousSocketChannel an abstract class implements AsynchronousByteChannel and NetworkChannel. This class is defined in the java.nio.channels package.

This is an asynchronous channel for stream-oriented and connecting network sockets.

An AsynchronousSocketChannel is created by invoking one of the open methods defined by this class. A newly created channel is open but not yet connected. A synchronous socket channel is connected when a connection is made to the socket of an AsynchronousServerSocketChannel using the connect() method; once connected, a channel remains connected until it is closed.

Channels of this type are safe for use by multiple concurrent threads. They support concurrent reading and writing, though at most one read operation and one write operation can be outstanding at any time.

2. The Example

The example is a client/server application program. The client uses a AsynchronousSocketChannel and the server a AsynchronousServerSocketChannel. The client sends messages and the server receives them. These are two independent programs.

2.1. The AsynchronousServerSocketChannel server

This is the server program.

2.1.1. Open a channel

AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();

2.1.2. Bind to a socket address

InetSocketAddress hostAddress = new InetSocketAddress("localhost", 3883);
serverChannel.bind(hostAddress);

The above code snippet shows binding the server channel’s socket to a local address. This configures the socket to listen for client connections.

2.1.3. Accept a connection

Future acceptResult = serverChannel.accept();
AsynchronousSocketChannel clientChannel = acceptResult.get();

The above code snippet shows the initiation of an asynchronous operation to accept a connection made to this channel’s socket – from a client. The pending result is a Future object of type AsynchronousSocketChannel. The future’s get() method returns the AsynchronousSocketChannel to the new connection on successful completion.

Note the program waits to accept until the client starts and connects on the port of this server.

2.1.4. Receive messages from client

The connected channel from the previous step reads a sequence of bytes into the given buffer. The read data is the message received from the client. The client program and the code to send messages are explained later in section 2.2. Client.

ByteBuffer buffer = ByteBuffer.allocate(32);
Future result = clientChannel.read(buffer);

The received message is printed.

String message = new String(buffer.array()).trim();
System.out.println(message);

The program receives messages from the client – runs in an infinite loop – until the client program sends a message “Bye.” indicating that there are no more messages (it’s the last message). Then the server program terminates.

2.1.5. Close

Close the connection channel and the server channel.

clientChannel.close();
serverChannel.close();

2.2. The AsynchronousSocketChannel client

This is the client program.

2.2.1. Open a channel

AsynchronousSocketChannel client = AsynchronousSocketChannel.open();

2.2.2. Connect to server

Connect this channel to the specified remote server’s address.

InetSocketAddress hostAddress = new InetSocketAddress("localhost", 3883);
Future future = client.connect(hostAddress);
future.get();

Note the socket address it is to connect is same server’s socket address receiving the connection (as specified in the previous section 2.1. Server). The connect() method returns a Future representing the pending result. The future’s get() method returns a null on successful connection.

After this step is run, the server is ready to receive the messages sent by this program.

2.3.3. Send messages to server

The client sends three pre-determined messages. The last of three, “Bye.” when sent to the server, the server verifies the message and terminates.

In the following code snippet, the channel’s write() method initiates an asynchronous write operation. This writes a sequence of bytes to this channel from the given buffer with message data.

String [] messages = new String [] {"Time goes fast.", "What now?", "Bye."};

for (int i = 0; i < messages.length; i++) {
    byte [] message = new String(messages [i]).getBytes();
    ByteBuffer buffer = ByteBuffer.wrap(message);
    Future result = client.write(buffer);

2.3.4. Close channel

All messages are sent to the server. Close the channel.

client.close();

3. The Code and the Output

The application has two programs – the client and the server. The following are the complete code, the run instructions and the output details.

3.1. Code

3.1.1. Server

ServerExample.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.net.InetSocketAddress;

public class ServerExample {

    public static void main (String [] args)
            throws Exception {
	
        new ServerExample().go();
    }
	
    private void go()
            throws IOException, InterruptedException, ExecutionException {

        AsynchronousServerSocketChannel serverChannel = AsynchronousServerSocketChannel.open();
        InetSocketAddress hostAddress = new InetSocketAddress("localhost", 3883);
        serverChannel.bind(hostAddress);
		
        System.out.println("Server channel bound to port: " + hostAddress.getPort());
        System.out.println("Waiting for client to connect... ");
		
        Future acceptResult = serverChannel.accept();
        AsynchronousSocketChannel clientChannel = acceptResult.get();

        System.out.println("Messages from client: ");

        if ((clientChannel != null) && (clientChannel.isOpen())) {

            while (true) {

                ByteBuffer buffer = ByteBuffer.allocate(32);
                Future result = clientChannel.read(buffer);

                while (! result.isDone()) {
                    // do nothing
                }

                buffer.flip();
                String message = new String(buffer.array()).trim();
                System.out.println(message);

                if (message.equals("Bye.")) {

                    break; // while loop
                }

                buffer.clear();

            } // while()

            clientChannel.close();
		
        } // end-if
		
        serverChannel.close();
    }
}

3.1.2. Client

ClientExample.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.Future;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.net.InetSocketAddress;

public class ClientExample {

    public static void main (String [] args)
            throws Exception {
	
        new ClientExample().go();
    }

    private void go()
            throws IOException, InterruptedException, ExecutionException {
	
        AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
        InetSocketAddress hostAddress = new InetSocketAddress("localhost", 3883);
        Future future = client.connect(hostAddress);
        future.get(); // returns null

        System.out.println("Client is started: " + client.isOpen());
        System.out.println("Sending messages to server: ");
		
        String [] messages = new String [] {"Time goes fast.", "What now?", "Bye."};
		
        for (int i = 0; i < messages.length; i++) {
		
            byte [] message = new String(messages [i]).getBytes();
            ByteBuffer buffer = ByteBuffer.wrap(message);
            Future result = client.write(buffer);
		
            while (! result.isDone()) {
                System.out.println("... ");
            }
		
            System.out.println(messages [i]);
            buffer.clear();
            Thread.sleep(3000);
		} // for
		
		client.close();
	}
}

3.2. The output

The two programs are to be started independently. Note the server program is started first.

3.2.1. Start the server

Start the server program in a new DOS window. The following is the output:

> java ServerExample

Server channel bound to port: 3883
Waiting for client to connect...

From the output note the server port 3883. The program waits to accept, until the client connects.

3.2.2. Start the client

Start the client program in another DOS window. The following is the output:

> java ClientExample

Client is started: true
Sending messages to server:
Time goes fast.
...
What now?
...
Bye.

From the output, note the client is started. This connects to the server’s port 3883. After connecting, three messages are sent to the server, one at a time.

3.2.3. Check messages on server

The following output shows the server receiving the three messages sent by the client, one at a time.

Server channel bound to port: 3883
Waiting for client to connect...

Messages from client:
Time goes fast.
What now?
Bye.

4. Download Java Source Code

This was an example of java.nio.channels.AsynchronousSocketChannel

Download
You can download the full source code of this example here: AsynchronousSocketChannelExamples.zip

Prasad Saya

Prasad Saya is a software engineer with over ten years’ experience in application development, maintenance, testing and consulting on various platforms. He is a certified Java and Java EE developer. At present his interest is in developing Java applications. He also has experience working with databases and ERP applications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button