- Netty at https://netty.io/
- Apache MINA at http://mina.apache.org/
The above implementations/frameworks have gone way past the point of being just "NIO Socket Servers". They are in fact fully evolved event based asynchronous systems you can use for a wide variety of needs.
Let's get down to business then, The following implementation simulates a request-reply.
The server simply listens for connections on a port and responds to valid requests with a reply.
The server simply listens for connections on a port and responds to valid requests with a reply.
package com.sockets.server; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.Date; public class ProcessSocketChannel implements Runnable { private SocketChannel socketChannel; private int BUFFER_SIZE = 1024; public ProcessSocketChannel(SocketChannel socketChannel) { this.socketChannel = socketChannel; Thread thread = new Thread(this); thread.start(); } public void run() { System.out.println("Connection received from " + socketChannel.socket().getInetAddress().getHostAddress()); readMessage(); sendMessage("This is the server!!"); } void sendMessage(String msg) { String fullmessage = new Date().toString() + " > " + msg; ByteBuffer buf = ByteBuffer.allocate(fullmessage.getBytes().length); buf.clear(); buf.put(fullmessage.getBytes()); buf.flip(); while (buf.hasRemaining()) { try { socketChannel.write(buf); } catch (IOException e) { e.printStackTrace(); } } } void readMessage() { ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); Charset charset = Charset.forName("us-ascii"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer; try { int bytes = socketChannel.read(byteBuffer); byteBuffer.flip(); charBuffer = decoder.decode(byteBuffer); String result = charBuffer.toString(); System.out.println(result); } catch (IOException e) { e.printStackTrace(); } finally { byteBuffer = null; charset = null; decoder = null; charBuffer = null; } } }
Processing of requests is delegated to a thread ProcessSocketChannel ,
package com.sockets.server; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.Date; public class ProcessSocketChannel implements Runnable { private SocketChannel socketChannel; private int BUFFER_SIZE = 1024; public ProcessSocketChannel(SocketChannel socketChannel) { this.socketChannel = socketChannel; Thread thread = new Thread(this); thread.start(); } public void run() { System.out.println("Connection received from " + socketChannel.socket().getInetAddress().getHostAddress()); readMessage(); sendMessage("This is the server!!"); } void sendMessage(String msg) { String fullmessage = new Date().toString() + " > " + msg; ByteBuffer buf = ByteBuffer.allocate(fullmessage.getBytes().length); buf.clear(); buf.put(fullmessage.getBytes()); buf.flip(); while (buf.hasRemaining()) { try { socketChannel.write(buf); } catch (IOException e) { e.printStackTrace(); } } } void readMessage() { ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); Charset charset = Charset.forName("us-ascii"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer; try { int bytes = socketChannel.read(byteBuffer); byteBuffer.flip(); charBuffer = decoder.decode(byteBuffer); String result = charBuffer.toString(); System.out.println(result); } catch (IOException e) { e.printStackTrace(); } finally { byteBuffer = null; charset = null; decoder = null; charBuffer = null; } } }
As for the client
package com.sockets.client; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.Date; public class Client { //The default buffer size private final int BUFFER_SIZE = 1024; private SocketChannel clientSocket; //The port of the server connecting to private int port = 7777; void run() { try { clientSocket = SocketChannel.open(); //Obtaining the localhost InetAddress host = InetAddress.getLocalHost(); //Connecting to server clientSocket.connect(new InetSocketAddress(host, port)); System.out.println(String.format("Connected to %s on port %d", host.getHostAddress(), port)); //Sending a message to the server sendMessage("Hello Server!!"); //Reading the reply sent from the server readMessage(); } catch (UnknownHostException unknownHost) { System.err.println("You are trying to connect to an unknown host!"); } catch (IOException ioException) { ioException.printStackTrace(); } finally { //Closing connection try { clientSocket.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } void sendMessage(String msg) throws IOException { String fullmessage = new Date().toString() + " > " + msg; ByteBuffer buf = ByteBuffer.allocate(fullmessage.getBytes().length); //Initialize the buffer buf.clear(); buf.put(fullmessage.getBytes()); //Flip the content of the buffer before writing buf.flip(); //Writing Buffer Content to socket while (buf.hasRemaining()) { clientSocket.write(buf); } } void readMessage() { //Reads a text message ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); Charset charset = Charset.forName("us-ascii"); CharsetDecoder decoder = charset.newDecoder(); CharBuffer charBuffer; try { int bytes = clientSocket.read(byteBuffer); byteBuffer.flip(); charBuffer = decoder.decode(byteBuffer); String result = charBuffer.toString(); System.out.println(result); } catch (IOException e) { e.printStackTrace(); } finally { byteBuffer = null; charset = null; decoder = null; charBuffer = null; } } public static void main(String args[]) { Client client = new Client(); client.run(); } }
While I admit that the above implementation is less than ideal, given that it captures the basics of socket communications, I think it's a good starting point for those who still care about how the clock actually ticks.
i hope u could talk about the advantage of using nio socketserver over io socketserver ...
ReplyDeleteI think you're missing part of the server code here (the main segment)! You posted package com.sockets.server twice!
ReplyDelete