Complete Example

To practice the knowledge we have learned in the previous sections, let’s see a complete client-server example

  1. We’ll build an echo server and an echo client.
  2. In this kind of setup, the client connects to the server and starts sending messages to it.
  3. The server echoes messages sent by each client.

When the server encounters a specific message, such as the end, it interprets it as the end of the communication and closes the connection with the client

Create a server: NIOServer.java

Java




//Java Program to test 
//echo server using NIO Selector
  
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
  
//Driver class for NIOServer
public class NIOServer {    
    
  //Main method
  public static void main(String[] args) throws IOException {
      
    // Create a new Selector        
    Selector selector = Selector.open();  
      
    // Create a ServerSocketChannel, bind it, and configure it as non-blocking        
    ServerSocketChannel serverChannel = ServerSocketChannel.open();        
    serverChannel.bind(new InetSocketAddress("localhost", 5454));        
    serverChannel.configureBlocking(false);        
      
    // Register the server socket channel with the Selector for accepting connections        
    serverChannel.register(selector, SelectionKey.OP_ACCEPT);        
    ByteBuffer buffer = ByteBuffer.allocate(256);        
    System.out.println("Server started and listening on port 5454...");        
    while (true) {            
        
      // Select ready channels using the Selector            
      selector.select();            
        
      // Get the set of selected keys            
      Set<SelectionKey> selectedKeys = selector.selectedKeys();            
      Iterator<SelectionKey> keyIterator = selectedKeys.iterator();  
        
      while (keyIterator.hasNext()) { 
          
        SelectionKey key = keyIterator.next();                
        if (key.isAcceptable()) {
            
          // Accept a new client connection                    
          ServerSocketChannel server = (ServerSocketChannel) key.channel(); 
          SocketChannel clientChannel = server.accept();                
          clientChannel.configureBlocking(false);                   
            
          // Register the client channel with the Selector for reading  
          clientChannel.register(selector, SelectionKey.OP_READ);                
        }                
        if (key.isReadable()) {                   
            
          // Read data from the client                    
          SocketChannel client = (SocketChannel) key.channel();                    
          buffer.clear();                    
          int bytesRead = client.read(buffer);                    
          if (bytesRead == -1) {                        
              
            // Client closed the connection                        
            key.cancel();                        
            client.close();                        
            continue;                    
          }                    
            
          buffer.flip();                    
          String receivedMessage = new String(buffer.array(), 0, bytesRead); 
            
          // Process the received message (e.g., echo it back to the client) 
          System.out.println("Received: " + receivedMessage);              
            
          // Prepare the buffer for writing and echo the received message back to the client 
          buffer.rewind();                    
          client.write(buffer);                
        }                
          
        // Remove the processed key from the set        
        keyIterator.remove();     
      }        
    }    
  }
}


Output of NIO Server:

Explanation

  • The code is a Java NIO implementation of an echo server.
  • It uses a Selector for efficient I/O handling.
  • Listens on port 5454, accepts connections, and echoes received data.
  • Non-blocking I/O allows handling multiple connections simultaneously.
  • The server loop monitors events on registered channels.
  • Accepted connections are registered for reading, and data is echoed back to clients.

Create a client: NIOClient.java

In this example we will create a NIOClient, using SocketChannel.

Java




//Java Program to create a 
//echo client using NIO Selector
  
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
  
  
//Driver class for NIOClient
public class NIOClient {    
    
  //Main method
  public static void main(String[] args) throws IOException {  
      
    // Create a socket channel and connect to the server     
    SocketChannel clientChannel = SocketChannel.open();     
    clientChannel.connect(new InetSocketAddress("localhost", 5454));  
    ByteBuffer buffer = ByteBuffer.allocate(256);     
    String message = "Hello, NIO Server!"
      
    // Message to send to the server       
    buffer.clear();       
    buffer.put(message.getBytes());       
    buffer.flip();       
      
    // Send the message to the server       
    while (buffer.hasRemaining()) {           
      clientChannel.write(buffer);        
    }        
    buffer.clear();       
      
    // Read the server's response       
    clientChannel.read(buffer);        
    buffer.flip();        
      
    // Convert the response to a String and print it        
    String response = new String(buffer.array(), 0, buffer.limit());        
    System.out.println("Server Response: " + response);        
    clientChannel.close();    
  }
}


Output of NIO Client:

Explanation of the above program:

  • Creates a SocketChannel and connects to a server at localhost on port 5454.
  • Prepares a message (“Hello, NIO Server!”) and sends it to the server.
  • Reads the server’s response into a buffer and converts it to a String.
  • Prints the server’s response.
  • Closes the client channel after communication.

java.nio.channels.Selector Class in Java

A selector is a tool that helps you keep an eye on one or more NIO channels and figure out when they’re ready to transfer data. In Java NIO, the Selector is a key player that looks at multiple Java NIO Channel instances and figures out which ones are good to go for actions like reading or writing.

This allows a single thread to handle many channels, making it easy to manage multiple network connections.

Similar Reads

Why Selector?

Using a selector helps us do more with fewer threads, just one instead of many. Frequent thread switching can burden the operating system and use up memory....

How to Create a Selector?

You can create a selector by simply using the open method of the Selector class. This method makes use of the system’s default selector provider to generate a fresh selector...

Registering Channel with the Selector

For a selector to monitor any channels, we must register these channels with the selector.This is done by calling the register method of the SelectableChannel. However, the channel must be in non-blocking mode before registering it with the selector:...

Selection Key

As you saw in the above section, when we register a Channel with a Selector the register() method returns a SelectionKey object. This SelectionKey object contains a few interesting properties:...

Channel Key Selection

Once we have registered one or more channels with a Selector, we can use one of the select() methods. These methods provide us with the channels that are “ready” for the events we care about (such as connect, accept, read, or write)....

Other Selector Methods

We have some more selector methods available mentioned with proper description and usage....

Practical Examples

Let’s explore a couple of practical examples to see the Selector class in action....

Complete Example

To practice the knowledge we have learned in the previous sections, let’s see a complete client-server example...

Conclusion

...