• Java nio Server端示例


    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();
            }
    
        }
    
    }
  • 相关阅读:
    Linux文件属性之用户和组基础知识介绍
    企业案例-文件删除企业生产故障模拟重现(未完成待续)
    Linux文件属性之Linux文件删除重要原理详解
    Linux文件属性之软硬连接知识深度详解
    Linux文件权限基础知识
    Linux文件属性拓展知识
    Linux 文件和目录的属性及权限
    linux优化之优化开机自启动服务
    (企业面试)描述Linux系统的启动过程?
    Linux企业面试题(一)
  • 原文地址:https://www.cnblogs.com/windliu/p/9588496.html
Copyright © 2020-2023  润新知