public class ServerNio {

    public static void main(String[] args) throws IOException, InterruptedException {
        //打开一个selector
        Selector selector = Selector.open();
        //打开serverSock通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //非阻塞模式
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.socket().bind(new InetSocketAddress(8099)); // bind address on port
        //向selector注册一个接受客户端事件,如果有客户端想和8099端口建立连接,selector会生成接受连接就绪事件
        SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, 1);

        try {
            while (true) {
                System.out.println("in while(true)");
                //select 注册的key whose channels are ready for I/O operations
                int count = selector.select();
                System.out.println("select count:" + count);

                //在无限循环中,就绪事件个数大于0时,进入逻辑处理流程
                if (count > 0) {
                    //获取就绪事件key
                    Set<SelectionKey> selectionKeySet = selector.selectedKeys();
                    Iterator<SelectionKey> selectionKeyIterator = selectionKeySet.iterator();

                    //遍历就绪的selectionKey
                    while ((selectionKeyIterator.hasNext())) {
                        SelectionKey key = selectionKeyIterator.next();
                        //先remove掉,防止重复处理
                        selectionKeyIterator.remove();

                        //如果key是建立连接请求
                        if (key.isAcceptable()) {
                            System.out.println("attachment:" + key.attachment());
                            ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                            //如果不处理,那么每次都能select到它,接受请求
                            SocketChannel socketChannel = channel.accept();
                            socketChannel.configureBlocking(false);
                            System.out.println("has accept channel");
                            //                            socketChannel.socket().setSoTimeout(2000);
                            //项selector注册读监控事件,可以考虑注册到另一个selector上去,让当前selector只处理accept
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        } else if (key.isReadable()) {
                            SocketChannel sc = (SocketChannel) key.channel();
                            if (!sc.isOpen()) {
                                System.out.println("in continue");
                                continue;
                            }

                            //开辟4个byte空间
                            ByteBuffer byteBuffer = ByteBuffer.allocate(4);
                            byteBuffer.clear();

                            //从sc中读取byte到buffer中
                            int bytesRead = sc.read(byteBuffer);
                            //断开连接了,-1就是socket关闭的意思
                            if (bytesRead == -1) {
                                sc.close();
                                System.out.println("client is out");
                                continue;
                            }
                            System.out.println("读取的byte个数:" + bytesRead);
                            if (bytesRead > 0) {
                                //切换为读模式
                                byteBuffer.flip();
                                //由于传输的是一个int,这里尝试将4个byte转回int
                                int value = 0;
                                value = value | ((byteBuffer.get(0) & 0xFF) << 24);
                                value = value | ((byteBuffer.get(1) & 0xFF) << 16);
                                value = value | ((byteBuffer.get(2) & 0xFF) << 8);
                                value = value | ((byteBuffer.get(3) & 0xff));

                                //读取到的值
                                System.out.println("transport value:int:" + value);
                            }
                            //                            sc.register(selector, SelectionKey.OP_WRITE);

                        } else if (key.isWritable()) {
                            //类似response
                            SocketChannel sc = (SocketChannel) key.channel();
                            ByteBuffer byteBuffer = ByteBuffer.allocate(4);
                            byteBuffer.clear();
                            byteBuffer.putInt(3);
                            sc.write(byteBuffer);
                            //                            sc.register(selector, SelectionKey.OP_READ);
                        }


                    }

                    System.out.println("selectionKeySize:" + selectionKeySet.size());
                }
                Thread.sleep(100);
            }
        } finally {
            Thread.sleep(20000);
            selector.close();
        }

    }

}
posted on 2018-10-09 19:32  j.liu&nbsp;windliu  阅读(226)  评论(0编辑  收藏  举报