简单的NIO例子

转载自 https://blog.csdn.net/howard2005/article/details/79367657
Server端:

public static void main(String[] args) throws Exception {
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(9999));
        System.out.println("Waiting for client...");

        Selector selector = Selector.open();
        ssc.register(selector, SelectionKey.OP_ACCEPT);

        while(true) {
            int select = selector.select();
            Set selectionKeys = selector.selectedKeys();
            Iterator iterator = selectionKeys.iterator();
            while(iterator.hasNext()) {
                SelectionKey sk = iterator.next();
                handleKey(selector, sk);
                iterator.remove();
            }
        }

    }
private static void handleKey(Selector selector, SelectionKey sk) throws IOException {
        if(sk.isAcceptable()) {
            ServerSocketChannel ss = (ServerSocketChannel)sk.channel();
            ss.configureBlocking(false);
            SocketChannel sc = ss.accept();
            sc.configureBlocking(false);
            System.out.println("有客户端接入,负责处理该请求的线程id:" + Thread.currentThread().getId());
            sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        }
        // 判断当前事件是否为read事件
        if (sk.isReadable()) {
            // 获取客户端通道
            SocketChannel sc = (SocketChannel) sk.channel();
            // 设置客户端通道非阻塞模式
            sc.configureBlocking(false);
            // 创建字节缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(10);
            // 读取通道数据存在字节缓冲区
            sc.read(buffer);
            // 输出服务器端读取的数据
            System.out.println("服务器端读到了数据:" + new String(buffer.array()) + Thread.currentThread().getId());
            // 去掉read事件
            // sc.register(selector, SelectionKey.OP_WRITE);
            sc.register(selector, sk.interestOps() & ~SelectionKey.OP_READ);
        }

        // 判断当前事件是否为write事件
        if (sk.isWritable()) {
            // 获取客户端通道
            SocketChannel sc = (SocketChannel) sk.channel();
            // 设置客户端通道非阻塞模式
            sc.configureBlocking(false);
            // 定义字节缓冲区存放了数据
            ByteBuffer buffer = ByteBuffer.wrap("天长地久".getBytes("utf-8"));
            // 将字节缓冲区数据写入通道
            sc.write(buffer);
            // 提示用户
            System.out.println("服务器端写入了数据。" + Thread.currentThread().getId());
            // 去掉write事件
            sc.register(selector, sk.interestOps() & ~SelectionKey.OP_WRITE);
        }
    }

Client端:

public static void main(String[] args) throws Exception {
        // 创建SocketChannel对象
        SocketChannel sc = SocketChannel.open();
        // 设置客户端通道非阻塞模式
        sc.configureBlocking(false);
        // 请求连接服务器
        sc.connect(new InetSocketAddress("127.0.0.1", 9999));

        // 确保客户端连接成功
        if (!sc.isConnected()) {
            sc.finishConnect();
        }
        // 提示用户
        System.out.println("连接成功!");

        // 定义字节缓冲区
        ByteBuffer buffer1 = ByteBuffer.wrap("HelloWorld".getBytes());
        // 将字节缓冲区数据写入通道
        sc.write(buffer1);
        // 提示用户
        System.out.println("客户端写入了数据。");

        // 定义字节缓冲区
        ByteBuffer buffer2 = ByteBuffer.allocate(100);
        // 读取通道数据存入字节缓冲区
        sc.read(buffer2);
        // 调用缓冲区反转方法
        buffer2.flip();
        // 输出字节缓冲区实际字节数
        System.out.println("缓冲区字节数:" + buffer2.limit());
        // 输出客户端读取的内容
        System.out.println("客户端读取的内容:" + new String(buffer2.array(), "utf-8"));

        // 让客户端持续工作
        while (true);
    }

你可能感兴趣的:(简单的NIO例子)