AIO and the underlying implementation

AIO: asynchronous non-blocking IO, when the system has IO operations, will have a separate thread, made it all the things that need to be addressed handed over to the local operating system to complete processing the operating system is complete, then the results returned to .

With problems common to boil water, for example, the server let go A boil water, A bottle tops in a switch, this switch will be notified when the water to a boil A water has been burned, then be handled by A, the main switch is through callback function to achieve.

 

In AIO mainly accomplished by the use CompletionHandler, CompletionHandler is a processing program for eliminating asynchronous I / O operation results.

There are two interface methods CompletionHandler completed and failed

 

  • void completed(V result,
                   A attachment)
    Called after the operation is completed.
    parameter
    result - Results I / O operations.
    attachment - attached to the target I / O operations at startup. 

 

  • void failed(Throwable exc,
                A attachment)
    Called when the operation fails.
    parameter
    exc - Exception indicates cause I / O operations fail
    attachment - attached to the target I / O operations at startup. 

 

 

The following is a learning process to find the AIO associated implementation code here to be a record:

 

Server:

package com.learn.aio.server;

import com.study.info.HostInfo;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

class EchoHandler implements CompletionHandler<Integer, ByteBuffer> {

    private AsynchronousSocketChannel clientChannel;
    private boolean exit;

    public EchoHandler (AsynchronousSocketChannel ClientChannel) {
         the this .clientChannel = ClientChannel; 
    } 

    @Override 
    public  void Completed (Integer Result, the ByteBuffer ByteBuffer) { 
        ByteBuffer.flip ();   // before reading the first reset 
        String = Read new new String (byteBuffer.array (), 0 , byteBuffer.remaining ()) the TRIM ();. 
        String outMsg = "[Echo]" + the Read;     // response information 
        IF ( "byebye" .equalsIgnoreCase (the Read)) { 
            outMsg = "service has been broken open, bye " ;
             the this .exit = to true;
        }
        this.echoWrite(outMsg);
    }

    private void echoWrite(String content){
        ByteBuffer buffer = ByteBuffer.allocate(100);
        buffer.put(content.getBytes());
        buffer.flip();
        this.clientChannel.write(buffer,buffer,new CompletionHandler<Integer,ByteBuffer>(){

            @Override
            public void completed(Integer result, ByteBuffer buf) {
                if (buf.hasRemaining()){
                    EchoHandler.this.clientChannel.write(buffer, buffer, this);
                }else {
                    if(EchoHandler.this.exit == false){
                        ByteBuffer readBuffer = ByteBuffer.allocate(100);
                        EchoHandler.this.clientChannel.read(readBuffer, readBuffer, new EchoHandler(EchoHandler.this.clientChannel));
                    }
                }
            }

            @Override
            public void failed(Throwable exc, ByteBuffer buf) {
                try {
                    EchoHandler.this.clientChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void failed(Throwable exc, ByteBuffer byteBuffer) {
        try {
            this.clientChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 连接接收的回调处理
class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel, AIOServerThread> {

    @Override
    public void completed(AsynchronousSocketChannel channel, AIOServerThread aioServerThread) {
        aioServerThread.getServerChannel().accept(aioServerThread, this);   // 接收连接
        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
        channel.read(byteBuffer, byteBuffer, new EchoHandler(channel));
    }

    @Override
    public void failed(Throwable exc, AIOServerThread aioServerThread) {
        System.out.println("客户端连接创建失败....");
        aioServerThread.getLatch () the countDown ();. 
    } 
} 

// set the server processing threads 
class AIOServerThread the implements the Runnable { 

    Private AsynchronousServerSocketChannel ServerChannel = null ;    // server channel 
    Private a CountDownLatch LATCH = null ;     // sync operation layer 

    public AIOServerThread () throws {Exception
         this .latch = new new a CountDownLatch (. 1 );
         this .serverChannel AsynchronousServerSocketChannel.open = ();     // open channel server 
        this.serverChannel.bind ( new new the InetSocketAddress (HostInfo.PORT)); 
        System.out.println ( "service is started, listening port:" + HostInfo.PORT); 
    } 

    public AsynchronousServerSocketChannel getServerChannel () {
         return ServerChannel; 
    } 

    public a CountDownLatch getLatch () {
         return LATCH; 
    } 

    @Override 
    public  void RUN () {
         the this .serverChannel.accept ( the this , new new AcceptHandler ());
         the try {
             the this .wait ();     // thread waits
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class AIOEchoServer {
    public static void main(String[] args) throws Exception{
        new Thread(new AIOServerThread()).start();
    }
}

 

 

Client:

package com.learn.aio.client;

import com.study.info.HostInfo;
import com.study.util.InputUtil;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

class ClientReadHandler implements CompletionHandler<Integer, ByteBuffer>{
    private AsynchronousSocketChannel clientChannel;
    private CountDownLatch latch;

    public ClientReadHandler(AsynchronousSocketChannel clientChannel, CountDownLatch latch) {
        this.clientChannel = clientChannel;
        this.latch = latch;
    }

    @Override
    public void completed(Integer result, ByteBuffer buffer) {
        buffer.flip();
        String readMsg = new String(buffer.array(), 0, buffer.remaining());
        System.out.println(readMsg);
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        try {
            this.clientChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.latch.countDown();
    }
}
class ClientWriteHandler implements CompletionHandler<Integer, ByteBuffer>{
    private AsynchronousSocketChannel clientChannel;
    private CountDownLatch latch;

    public ClientWriteHandler(AsynchronousSocketChannel clientChannel, CountDownLatch latch) {
        this.clientChannel = clientChannel;
        this.latch = latch;
    }

    @Override
    public void completed(Integer result, ByteBuffer buffer) {
        if(buffer.hasRemaining()){
            this.clientChannel.write(buffer, buffer, this);
        }else {
            ByteBuffer readBuffer = ByteBuffer.allocate(100);
            this.clientChannel.read(readBuffer, readBuffer, new ClientReadHandler(this.clientChannel, this.latch));
        }
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        try {
            this.clientChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.latch.countDown();
    }
}

class AIOClientThread implements Runnable {

    private AsynchronousSocketChannel clientChannel;
    private CountDownLatch latch;

    public AIOClientThread() throws Exception{
        this.clientChannel = AsynchronousSocketChannel.open();
        this.clientChannel.connect(new InetSocketAddress(HostInfo.HOST_NAME, HostInfo.PORT));
        this.latch = new CountDownLatch(1);
    }

    @Override
    public void run() {
        try {
            this.latch.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public boolean sendMessage(String msg){
        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
        byteBuffer.put(msg.getBytes());
        byteBuffer.flip();
        this.clientChannel.write(byteBuffer, byteBuffer, new ClientWriteHandler(this.clientChannel, this.latch));
        if("byebye".equalsIgnoreCase(msg)){
            return false;
        }
        return  true;
    }
}

public class AIOEchoClient {
    public static void main(String[] args) throws Exception{
        AIOClientThread clientThread = new AIOClientThread();
        new Thread(clientThread).start();
        while(clientThread.sendMessage (InputUtil.getString ( "Please enter the content to be transmitted:" ))) { 

        } 
    } 
}

 

 

other:

package com.study.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class InputUtil {
    private static final BufferedReader KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));

    private InputUtil(){
    }

    public static String getString(String prompt){
        boolean flag = true;    //数据接受标记
        String str = null;
        while(In Flag) { 
            System.out.println (prompt); 
            the try { 
                STR = KEYBOARD_INPUT.readLine ();     // read a line of data 
                IF (STR == null || "" .equals (STR)) { 
                    the System.out. the println ( "data entry errors, NOT nULL!" ); 
                } the else { 
                    In Flag = to false ; 
                } 
            } the catch (IOException E) { 
                e.printStackTrace (); 
            } 
        } 
        return STR; 
    } 
}
package com.study.info;

public interface HostInfo {
    public static final String HOST_NAME = "localhost";
    public static final int PORT = 9999;
}

 

Guess you like

Origin www.cnblogs.com/shlearn/p/11706208.html