Try to implement TCP / IP + NIO with JAVA

This article uses Java 10.0.1 installed on WIN10.

at first

Last time I made a BIO transfer path, today I will continue to implement NIO.

About NIO

What is NIO

Simply put, it doesn't block I / O requests. You can improve existing I / O processing (BIO).

Bad points of BIO

First, for the request from the client side, two parts, a connection request and an I / O request, are included. Connection requests are always made, but I / O requests are made from time to time. Therefore, the method of preparing one processing thread regardless of one request regardless of whether or not there is I / O processing such as BIO wastes the performance of the server.

Good points of NIO

NIO has only one processing thread for every request from the client side. If there is an I / O request, ask another thread for I / O processing.

Implementation

*** SocketChannel *** and *** ServerSocketChannel *** are provided from the Java language, so this time I will try to implement TCP / IP + NIO using these. (Official API is here: SocketChannel, [ServerSocketChannel](https://docs .oracle.com/javase/jp/8/docs/api/java/nio/channels/ServerSocketChannel.html) Server side files

** Contents of ChannelServer.java **

public class ChannelServer {

    public static void main(String[] args) throws IOException {
        // I/Prepare a thread pool to process O requests
        ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10, 1000, TimeUnit.MILLISECONDS, 
                new ArrayBlockingQueue<Runnable>(100));

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(1234));

        while (true) {
            SocketChannel socketChannel = serverSocketChannel.accept();

            if (socketChannel != null) {
                //Commit the request to the thread pool
                executor.submit(new ChannelServerThread(socketChannel));
            }
        }
    }
}

** Contents of ChannelServer.java **

*** Thread to process request ***


public class ChannelServerThread implements Runnable {

    private SocketChannel socketChannel;
    private String remoteName;

    public ChannelServerThread(SocketChannel socketChannel) throws IOException {
        this.socketChannel = socketChannel;
        this.remoteName = socketChannel.getRemoteAddress().toString();
        System.out.println("client:" + remoteName + " access successfully!");
    }

    // I/Handle O request
    @Override
    public void run() {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        ByteBuffer sizeBuffer = ByteBuffer.allocate(4);
        StringBuilder sb = new StringBuilder();
        byte b[];
        //Read data and length from socketChannel and output to standard output
        while(true) {
            try {
                sizeBuffer.clear();
                int read = socketChannel.read(sizeBuffer);
                if (read != -1) {
                    sb.setLength(0);
                    sizeBuffer.flip();
                    int size = sizeBuffer.getInt();
                    int readCount = 0;
                    b = new byte[1024];
                    while (readCount < size) {
                        buffer.clear();
                        read = socketChannel.read(buffer);
                        if (read != -1) {
                            readCount += read;
                            buffer.flip();
                            int index = 0 ;
                            while(buffer.hasRemaining()) {
                                b[index++] = buffer.get();
                                if (index >= b.length) {
                                    index = 0;
                                    sb.append(new String(b,"UTF-8"));
                                }
                            }
                            if (index > 0) {
                                sb.append(new String(b,"UTF-8"));
                            }
                        }
                    }
                    System.out.println(remoteName +  ":" + sb.toString());
                }
            } catch (Exception e) {
                System.out.println(remoteName + "access colsed");
                try {
                    socketChannel.close();
                } catch (IOException ex) {
                }
                break;
            }
        }
    }
}

** Client-side files **

*** Creates a socketChannel and accesses the specified server and port ***

public class ChannelClient {

    public static void main(String[] args) throws IOException {

        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress(1234));
        while (true) {
            Scanner sc = new Scanner(System.in);
            String next = sc.next();
            sendMessage(socketChannel, next);
        }
    }

    //Prepare a container for Channel to IPO
    public static void sendMessage(SocketChannel socketChannel, String mes) throws IOException {
        if (mes == null || mes.isEmpty()) {
            return;
        }
        byte[] bytes = mes.getBytes("UTF-8");
        int size = bytes.length;
        ByteBuffer buffer = ByteBuffer.allocate(size);
        ByteBuffer sizeBuffer = ByteBuffer.allocate(4);

        sizeBuffer.putInt(size);
        buffer.put(bytes);

        buffer.flip();
        sizeBuffer.flip();
        ByteBuffer dest[] = {sizeBuffer,buffer};
        while (sizeBuffer.hasRemaining() || buffer.hasRemaining()) {
            socketChannel.write(dest);
        }
    }
}

Result authentication

*** Starting the server and waiting for a connection: ***

server

PS C:\Users\ma\Documents\work\socket\nio_tcp> java ChannelServer

*** Launch clients 1 and 2 respectively and enter something: ***

** Client 1 **


PS C:\Users\ma\Documents\work\socket\nio_tcp> java ChannelClient
iamfirstuser!
byebyefirstone!
Exception in thread "main"
PS C:\Users\ma\Documents\work\socket\nio_tcp>

** Client 2 **

java ChannelClient
iamseconduser
byebyesecondone!
Exception in thread "main"
PS C:\Users\ma\Documents\work\socket\nio_tcp>

server


PS C:\Users\ma\Documents\work\socket\nio_tcp> java ChannelServer
client:/192.168.56.1:50138 access successfully!
client:/192.168.56.1:50139 access successfully!
/192.168.56.1:50138:iamfirstuser!
/192.168.56.1:50139:iamseconduser
/192.168.56.1:50138:byebyefirstone!
/192.168.56.1:50138access colsed
/192.168.56.1:50139:byebyesecondone!
/192.168.56.1:50139access colsed

Summary

This time, I made a TCP / IP + NIO transfer path using Java's SocketChannel and ServerSocketChannel libraries. We were also able to authenticate that one server can handle multiple requests at the same time.

Recommended Posts

Try to implement TCP / IP + NIO with JAVA
I tried to implement TCP / IP + BIO with JAVA
[Java] Try to implement using generics
Try to implement Yubaba in Java
Try to implement n-ary addition in Java
Try to implement login function with Spring-Boot
Try to link Ruby and Java with Dapr
Try to implement login function with Spring Boot
I tried to implement Stalin sort with Java Collector
Java to play with Function
Try DB connection with Java
Try gRPC with Java, Maven
Connect to DB with Java
Connect to MySQL 8 with Java
[Java] How to implement multithreading
I want to implement various functions with kotlin and java!
Java to learn with ramen [Part 1]
[Java EE] Implement Client with WebSocket
Try to implement Yubaba in Ruby
[Java] Points to note with Arrays.asList ()
Try to implement iOS14 Widget function
Dare to challenge Kaggle with Java (1)
Try using Redis with Java (jar)
I tried to interact with Java
Try to imitate marshmallows with MiniMagick
Try to extract java public method
Try bidirectional communication with gRPC Java
Java, arrays to start with beginners
Try to speed up Java console program startup with GraalVM native-image
Interface Try to make Java problem TypeScript 7-3
How to implement date calculation in Java
Try to solve Project Euler in Java
How to compile Java with VsCode & Ant
[Java] How to compare with equals method
Let's try WebSocket with Java and javascript!
Introduction to algorithms with java --Search (depth-first search)
[Swift] Easy to implement modal with PanModal
How to implement coding conventions in Java
How to implement TextInputLayout with validation function
Try to implement UIAlertController by separating files
Try managing Java libraries with AWS CodeArtifact
Easy to trip with Java regular expressions
Try using the Wii remote with Java
I tried to implement ModanShogi with Kinx
Introduction to algorithms with java --Search (breadth-first search)
Try connecting to the Autonomous Database with JDK6 (Java) + JDBC OCI Driver (type 2).
Challenge to deal with garbled characters with Java AudioSystem.getMixerInfo ()
Let's write Java file input / output with NIO
[Java] How to test for null with JUnit
Try to build Java8 environment on Amazon Linux2
I tried to make Basic authentication with Java
Introduction to algorithms with java --Search (bit full search)
Deploy Java web app to Azure with maven
Try to create a bulletin board in Java
How to use Java framework with AWS Lambda! ??
Increment behavior Try to make Java problem TypeScript 3-4
I tried to implement deep learning in Java
I want to use java8 forEach with index
String operation Try to make Java problem TypeScript 9-3
How to use Java API with lambda expression
Getting started with Kotlin to send to Java developers