Java NIO
is my favorite topic. I have been working with NIO since last 2 years and would like to share simple Server-Client code
for my readers who are free to use this code in their production environment.
Starting JDK 1.4, NIO was created to allow all Java programmers to implement very high-speed input/output without having to deal with custom native code. NIO uses java.nio.buffer
library compare to simple I/O which drains and fills back buffer internally any operating system.
In this tutorial we will go over java.nio.channels
and java.nio.channels.Selector
libraries.
channels
represent connections to entities that are capable of performing I/O operations, such as files and sockets; defines selectors, for multiplexed, non-blocking I/O operations.selector
may be created by invoking the open method
of this class, which will use the system’s default selector provider to create a new selector.If you have below questions
then you are at right place:
CrunchifyNIOServer.java
which opens connection on port 1111
isAcceptable()
to check if channel is ready to accept a new socket connection isReadable()
to check if channel is ready for reading CrunchifyNIOClient.java
which tries to connect to server on port 1111
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | package crunchify.com.tutorials; 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; /** * @author Crunchify.com * */ public class CrunchifyNIOServer { @SuppressWarnings("unused") public static void main(String[] args) throws IOException { // Selector: multiplexor of SelectableChannel objects Selector selector = Selector.open(); // selector is open here // ServerSocketChannel: selectable channel for stream-oriented listening sockets ServerSocketChannel crunchifySocket = ServerSocketChannel.open(); InetSocketAddress crunchifyAddr = new InetSocketAddress("localhost", 1111); // Binds the channel's socket to a local address and configures the socket to listen for connections crunchifySocket.bind(crunchifyAddr); // Adjusts this channel's blocking mode. crunchifySocket.configureBlocking(false); int ops = crunchifySocket.validOps(); SelectionKey selectKy = crunchifySocket.register(selector, ops, null); // Infinite loop.. // Keep server running while (true) { log("i'm a server and i'm waiting for new connection and buffer select..."); // Selects a set of keys whose corresponding channels are ready for I/O operations selector.select(); // token representing the registration of a SelectableChannel with a Selector Set<SelectionKey> crunchifyKeys = selector.selectedKeys(); Iterator<SelectionKey> crunchifyIterator = crunchifyKeys.iterator(); while (crunchifyIterator.hasNext()) { SelectionKey myKey = crunchifyIterator.next(); // Tests whether this key's channel is ready to accept a new socket connection if (myKey.isAcceptable()) { SocketChannel crunchifyClient = crunchifySocket.accept(); // Adjusts this channel's blocking mode to false crunchifyClient.configureBlocking(false); // Operation-set bit for read operations crunchifyClient.register(selector, SelectionKey.OP_READ); log("Connection Accepted: " + crunchifyClient.getLocalAddress() + "\n"); // Tests whether this key's channel is ready for reading } else if (myKey.isReadable()) { SocketChannel crunchifyClient = (SocketChannel) myKey.channel(); ByteBuffer crunchifyBuffer = ByteBuffer.allocate(256); crunchifyClient.read(crunchifyBuffer); String result = new String(crunchifyBuffer.array()).trim(); log("Message received: " + result); if (result.equals("Crunchify")) { crunchifyClient.close(); log("\nIt's time to close connection as we got last company name 'Crunchify'"); log("\nServer will keep running. Try running client again to establish new connection"); } } crunchifyIterator.remove(); } } } private static void log(String str) { System.out.println(str); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | package crunchify.com.tutorials; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.ArrayList; /** * @author Crunchify.com * */ public class CrunchifyNIOClient { public static void main(String[] args) throws IOException, InterruptedException { InetSocketAddress crunchifyAddr = new InetSocketAddress("localhost", 1111); SocketChannel crunchifyClient = SocketChannel.open(crunchifyAddr); log("Connecting to Server on port 1111..."); ArrayList<String> companyDetails = new ArrayList<String>(); // create a ArrayList with companyName list companyDetails.add("Facebook"); companyDetails.add("Twitter"); companyDetails.add("IBM"); companyDetails.add("Google"); companyDetails.add("Crunchify"); for (String companyName : companyDetails) { byte[] message = new String(companyName).getBytes(); ByteBuffer buffer = ByteBuffer.wrap(message); crunchifyClient.write(buffer); log("sending: " + companyName); buffer.clear(); // wait for 2 seconds before sending next message Thread.sleep(2000); } crunchifyClient.close(); } private static void log(String str) { System.out.println(str); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | i'm a server and i'm waiting for new connection and buffer select... Connection Accepted: /127.0.0.1:1111 i'm a server and i'm waiting for new connection and buffer select... Message received: Facebook i'm a server and i'm waiting for new connection and buffer select... Message received: Twitter i'm a server and i'm waiting for new connection and buffer select... Message received: IBM i'm a server and i'm waiting for new connection and buffer select... Message received: Google i'm a server and i'm waiting for new connection and buffer select... Message received: Crunchify It's time to close connection as we got last company name 'Crunchify' Server will keep running. Try running client again to establish new connection i'm a server and i'm waiting for new connection and buffer select... |
1 2 3 4 5 6 | Connecting to Server on port 1111... sending: Facebook sending: Twitter sending: IBM sending: Google sending: Crunchify |
socket.setKeepAlive(true);
to have connections alive from client side.readLine()
call will be blocked until all data will be returned, so don’t use it. Try reading bytes from the stream until -1 is returned.
Let me know if that works.
SSISO Community