Skip to content

Commit

Permalink
Add Java NIO code snippets
Browse files Browse the repository at this point in the history
  • Loading branch information
100yo committed Jan 5, 2024
1 parent e6f23d9 commit 422bde7
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package bg.sofia.uni.fmi.mjt.echo.nio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.nio.channels.Channels;
import java.nio.channels.SocketChannel;
import java.util.Scanner;

// NIO specifics wrapped & hidden
public class EchoClient {

private static final int SERVER_PORT = 7777;

public static void main(String[] args) {

try (SocketChannel socketChannel = SocketChannel.open();
BufferedReader reader = new BufferedReader(Channels.newReader(socketChannel, "UTF-8"));
PrintWriter writer = new PrintWriter(Channels.newWriter(socketChannel, "UTF-8"), true);
Scanner scanner = new Scanner(System.in)) {

socketChannel.connect(new InetSocketAddress("localhost", SERVER_PORT));

System.out.println("Connected to the server.");

while (true) {
System.out.print("Enter message: ");
String message = scanner.nextLine(); // read a line from the console

if ("quit".equals(message)) {
break;
}

System.out.println("Sending message <" + message + "> to the server...");

writer.println(message);

String reply = reader.readLine(); // read the response from the server
System.out.println("The server replied <" + reply + ">");
}
} catch (IOException e) {
throw new RuntimeException("There is a problem with the network communication", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package bg.sofia.uni.fmi.mjt.echo.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Scanner;

// NIO, blocking
public class EchoClientNio {

private static final int SERVER_PORT = 7777;
private static final String SERVER_HOST = "localhost";
private static final int BUFFER_SIZE = 512;

private static ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);

public static void main(String[] args) {

try (SocketChannel socketChannel = SocketChannel.open();
Scanner scanner = new Scanner(System.in)) {

socketChannel.connect(new InetSocketAddress(SERVER_HOST, SERVER_PORT));

System.out.println("Connected to the server.");

while (true) {
System.out.print("Enter message: ");
String message = scanner.nextLine(); // read a line from the console

if ("quit".equals(message)) {
break;
}

System.out.println("Sending message <" + message + "> to the server...");

buffer.clear(); // switch to writing mode
buffer.put(message.getBytes()); // buffer fill
buffer.flip(); // switch to reading mode
socketChannel.write(buffer); // buffer drain

buffer.clear(); // switch to writing mode
socketChannel.read(buffer); // buffer fill
buffer.flip(); // switch to reading mode

byte[] byteArray = new byte[buffer.remaining()];
buffer.get(byteArray);
String reply = new String(byteArray, "UTF-8"); // buffer drain

// if buffer is a non-direct one, is has a wrapped array and we can get it
//String reply = new String(buffer.array(), 0, buffer.position(), "UTF-8"); // buffer drain

System.out.println("The server replied <" + reply + ">");
}

} catch (IOException e) {
throw new RuntimeException("There is a problem with the network communication", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package bg.sofia.uni.fmi.mjt.echo.nio;

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;

public class EchoServer {
public static final int SERVER_PORT = 7777;
private static final String SERVER_HOST = "localhost";
private static final int BUFFER_SIZE = 1024;

public static void main(String[] args) {
try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open()) {

serverSocketChannel.bind(new InetSocketAddress(SERVER_HOST, SERVER_PORT));
serverSocketChannel.configureBlocking(false);

Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);

while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) {
// select() is blocking but may still return with 0, check javadoc
continue;
}

Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();

buffer.clear();
int r = sc.read(buffer);
if (r < 0) {
System.out.println("Client has closed the connection");
sc.close();
continue;
}
buffer.flip();
sc.write(buffer);

} else if (key.isAcceptable()) {
ServerSocketChannel sockChannel = (ServerSocketChannel) key.channel();
SocketChannel accept = sockChannel.accept();
accept.configureBlocking(false);
accept.register(selector, SelectionKey.OP_READ);
}

keyIterator.remove();
}

}

} catch (IOException e) {
throw new RuntimeException("There is a problem with the server socket", e);
}
}
}

0 comments on commit 422bde7

Please sign in to comment.