netty入门(原生jdk nio写一个服务器)

jdk nio 服务器

引言

在学习netty之前我们需要了解nio,于是我就想分享一下如何用jdk nio写一个服务

流程

步骤1:打开一个服务管道(Channel),并设置非阻塞模式
步骤2:创建服务
步骤3:打开一个多路复用器,并注册到Channel,对ACCEPT事件感兴趣
步骤4:轮询选择多路复用器,针对不同的复用器进行相关的操作(读、写)

public class NoUseNettyNio {
    public void serve(int port) throws IOException {

        //打开一个ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //设置一个serverSocketChannel为不阻塞模式,即nio
        serverSocketChannel.configureBlocking(false);
        //通过serverSocketChannel获取serverSocket
        ServerSocket serverSocket = serverSocketChannel.socket();
        //创建一个server的网卡地址对象
        InetSocketAddress address = new InetSocketAddress(port);
        //为serverSocket绑定网卡地址
        serverSocket.bind(address);
        //打开一个selector(多路复用器)
        Selector selector = Selector.open();
        //将多路复用器注册到serverSocketChannel(管道)上
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //创建一个byteBuffer
        ByteBuffer buffer = ByteBuffer.wrap(("HTTP/1.1 200 OK\r\n" +
                "        Content-Type: text/html;charset=UTF-8\r\n").getBytes(StandardCharsets.UTF_8));
        for (; ; ) {
            try {
                //选择一个通道,此方法是阻塞的,在有一个通道、线程中断或Selector的唤醒时,返回
                selector.select();
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
            //获取的一个selectKey集合,该集合只能删除不能添加,
            Set selectionKeys = selector.selectedKeys();
            Iterator iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                try {
                    if (key.isAcceptable()) {
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        client.configureBlocking(false);
                        client.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE,buffer.duplicate());
                        System.out.println("Accepted connection from "+client);
                    }
                    if(key.isWritable()) {
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer attachment = (ByteBuffer) key.attachment();
                        while (buffer.hasRemaining()) {
                            System.out.println(attachment.toString());
                            if(client.write(attachment) == 0) {
                                break;
                            }
                        }
                        client.close();
                    }
                } catch (IOException e) {
                    key.channel();
                    try {
                        key.channel().close();
                    } catch (IOException ex) {
                    }
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        NoUseNettyNio noUseNettyNio = new NoUseNettyNio();
        noUseNettyNio.serve(8910);
    }
}

你可能感兴趣的:(javanetty后端)