4、java.nio、ServerSocketChannel Selector 非阻塞IO多路复用简单实用

客户端参考:https://www.jianshu.com/p/027af54275f3

public static void main(String[] args) throws Exception {
    // 打开一个多路io复用管理器
    Selector selector = Selector.open();
    // 打开一个tcp通道
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    // 设置非阻塞模式
    serverSocketChannel.configureBlocking(false);
    // 绑定监听本地ip端口
    serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8080));
    // 注册连接事件
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    while (true) {
      // 此方法会阻塞直到有io准备好
      selector.select();
      // 获取key迭代器
      Iterator selectionKeyIterator = selector.selectedKeys().iterator();
      // 如果有key
      while (selectionKeyIterator.hasNext()) {
        // 获取一个key
        SelectionKey selectionKey = selectionKeyIterator.next();
        // 删除获取到的key以免重复获取
        selectionKeyIterator.remove();
        // 如果是连接事件
        if (selectionKey.isAcceptable()) {
          // 获取和客户端连接的通道
          ServerSocketChannel sc = (ServerSocketChannel) selectionKey.channel();
          SocketChannel socketChannel = sc.accept();
          // 设置非阻塞模式
          socketChannel.configureBlocking(false);
          // 赋予读写通道的权限
          socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
          // 发一条数据给客户端
          socketChannel.write(ByteBuffer.wrap("我是服务端发来的".getBytes()));
          // 判断到可读的事件
        } else if (selectionKey.isReadable()) {
          // 得到此事件的socket通道
          SocketChannel sc = (SocketChannel) selectionKey.channel();
          ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
          int i = sc.read(byteBuffer);
          // -1表示客户端已关闭并且没有数据了
          //正确做法是while(sc.read(byteBuffer)>0)  一直接收,demo就简单写了
          if (i != -1) {
            byte[] data = new byte[i];
            byteBuffer.flip();
            byteBuffer.get(data);
            System.out.println("服务器收到消息: " + new String(data));
          }
        }
      }
    }
  }

你可能感兴趣的:(4、java.nio、ServerSocketChannel Selector 非阻塞IO多路复用简单实用)