JDK NIO

一、说明:

Jdk  nio 样例代码
先记录一下

二、代码:

服务端代码
import java.io.IOException;
import java.net.InetAddress;
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.nio.charset.StandardCharsets;
import java.util.Iterator;

public class TestJdkNioServer {

    public static void main(String[] args) throws Exception {
        JdkNioServerDemo.class.newInstance().exec();
    }
}

class JdkNioServerDemo {

    ServerSocketChannel serverSocketChannel;

    Selector selector;

    ByteBuffer readBuffer;

    ByteBuffer writeBuffer;

    public void exec() {

        this.readBuffer = ByteBuffer.allocate(1024);
        this.writeBuffer = ByteBuffer.allocate(1024);

        this.initServerConfiguration();

        this.listenServerConnection();
    }

    private void initServerConfiguration() {
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.socket().bind(new InetSocketAddress(InetAddress.getLocalHost(), 7001));
            System.out.println("listening on port 7001");
            this.selector = Selector.open();
            serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void listenServerConnection() {

        try {
            while (this.selector.select() > 0) {

                Iterator<SelectionKey> selectionKeyIterator = this.selector.selectedKeys().iterator();
                while (selectionKeyIterator.hasNext()) {
                    SelectionKey selectionKey = selectionKeyIterator.next();
                    try {
                        selectionKeyIterator.remove();

                        if (selectionKey.isAcceptable()) {
                            this.acceptedNewConnection(selectionKey);
                        }

                        if (selectionKey.isReadable()) {
                            this.readRequest(selectionKey);
                        }

                        if (selectionKey.isWritable()) {
//                    this.readRequest(selectionKey);
                        }
                    } catch (IOException ex) {
                        System.out.println(ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage());
                        this.doClose(selectionKey);
                    }
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    private void acceptedNewConnection(SelectionKey selectionKey) throws IOException {
        System.out.println("accept a new connection");
        ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();

        SocketChannel socketChannel = server.accept();
        if (socketChannel == null) {
            return;
        }

        socketChannel.configureBlocking(false);
        socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        byteBuffer.put(StandardCharsets.UTF_8.encode("hello " + socketChannel.getRemoteAddress()));
        byteBuffer.flip();
        socketChannel.write(byteBuffer);

        System.out.println(socketChannel.getRemoteAddress());
    }

    private void readRequest(SelectionKey selectionKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        int read = socketChannel.read(this.readBuffer);
        if (read > 0) {
            this.readBuffer.flip();
            byte[] bytes = new byte[this.readBuffer.remaining()];
            this.readBuffer.get(bytes);
            this.readBuffer.clear();

            String requestBody = new String(bytes, StandardCharsets.UTF_8.name());
            System.out.println("handle a request: " + requestBody);

            this.wirteResponse(selectionKey, requestBody);
        }

        if (read == 0) {
        }

        if (read < 0) {
            this.doClose(selectionKey);
        }
    }

    private void wirteResponse(SelectionKey selectionKey, String requestBody) throws IOException {
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        this.writeBuffer.clear();
        this.writeBuffer.put(StandardCharsets.UTF_8.encode("request message." + requestBody + " handled."));
        this.writeBuffer.flip();
        socketChannel.write(this.writeBuffer);
        this.writeBuffer.compact();
    }

    private void doClose(SelectionKey selectionKey) {
        try {
            selectionKey.cancel();
            selectionKey.channel().close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}
客户端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

public class TestJdkNioClient {

    public static void main(String[] args) throws Exception {
        JdkNioClientDemo.class.newInstance().exec();
    }
}

class JdkNioClientDemo {

    private final ByteBuffer sendBuffer = ByteBuffer.allocate(1024);

    private final ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);

    private Selector selector;

    public void exec() throws IOException {

        new Thread(this::readUserInput).start();

        this.initConnection();

        this.ioReadAndWriteHandle();

    }

    private void initConnection() throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress(InetAddress.getLocalHost(), 7001));

        socketChannel.configureBlocking(false);

        System.out.println("connection sucessful.");

        selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    }


    private void sendRequest(SelectionKey selectionKey) throws IOException {
        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
        if (socketChannel == null) {
            return;
        }

        synchronized (sendBuffer) {
            sendBuffer.flip();
            while (sendBuffer.hasRemaining()) {
                socketChannel.write(sendBuffer);
            }
            sendBuffer.compact();
        }
    }


    private void readResponse(SelectionKey selectionKey) throws IOException {
        SocketChannel channel = (SocketChannel) selectionKey.channel();
        channel.read(this.receiveBuffer);
        this.receiveBuffer.flip();

        String response = StandardCharsets.UTF_8.decode(this.receiveBuffer).toString();
        System.out.println("response: " + response);
        this.receiveBuffer.clear();
    }

    private void readUserInput() {

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String requestCommond;
        try {
            while ((requestCommond = reader.readLine()) != null) {
                synchronized (sendBuffer) {
                    sendBuffer.put(StandardCharsets.UTF_8.encode(requestCommond + "\n"));
                }
            }
        } catch (IOException ex) {
        }
    }

    private void ioReadAndWriteHandle() throws IOException {
        try {
            while (this.selector.select(1) > 0) {
                Iterator<SelectionKey> selectionKeyIterator = this.selector.selectedKeys().iterator();
                while (selectionKeyIterator.hasNext()) {
                    SelectionKey selectionKey = selectionKeyIterator.next();
                    selectionKeyIterator.remove();

                    if (selectionKey.isReadable()) {
                        this.readResponse(selectionKey);
                    }

                    if (selectionKey.isWritable()) {
                        this.sendRequest(selectionKey);
                    }
                }

                TimeUnit.MILLISECONDS.sleep(3);
            }
        } catch (IOException ex) {
        } catch (InterruptedException ex) {
        }
    }

}

三、运行结果:

posted @ 2021-11-18 15:18  马金鹏  阅读(89)  评论(0)    收藏  举报