Java IO多路复用技术简介(3)

/**
    * 轮询监听selector刚兴趣的事件.
    */
    @Override
    public void run() {
        try {
            System.out.println("第" + index + "个客户端启动!");
            // 先尝试异步连接服务器, 如果连接成功,则只需要把channel注册到selector的READ事件,
            // 读取服务器返回的结果. 如果不成功(客户端已经向服务器发送了sync包,但是服务器没有返回ack包, 物理链路还没建立成功)
            // 则把该channel注册到selector的CONNECT事件, 等待服务器返回的ack包.
            if (channel.connect(new InetSocketAddress(8080))) {
                channel.register(selector, SelectionKey.OP_READ);
                doWrite(channel, TIME_ORDER);
            } else {
                channel.register(selector, SelectionKey.OP_CONNECT);
            }
            while (!stop) {
                selector.select(1000);
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    SocketChannel sc = (SocketChannel) key.channel();
                    iterator.remove();
                    if (key.isValid()) {
                        if (key.isReadable()) {  // 监听到可读事件, 读取服务器返回的处理结果.
                            ByteBuffer buff = ByteBuffer.allocate(1024);
                            int size = sc.read(buff);
                            if (size > 0) {
                                byte[] b = new byte[size];
                                buff.flip();
                                buff.get(b);
                                System.out.println("第" + index + "个客户端获取服务器返回时间:" + new String(b));
                                stop = true;
                            } else if (size < 0) {
                                sc.close();
                                key.cancel();
                            } else {
                                ;
                            }
                        }
                        if (key.isConnectable()) {  //监听到服务器返回了ack包, 准备完成连接的建立
                            if (sc.finishConnect()) {  // 调用此方法完成物理链路连接的建立
                                sc.register(selector, SelectionKey.OP_READ); // 建立连接之后注册监听READ事件
                                doWrite(sc, TIME_ORDER);
                            } else {
                                System.exit(1);  //否则,程序退出
                            }
                        }
                    }
                }
            }
            if (selector != null) {
                selector.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8d4ecd5ba8b62a53f2b9ad15127ee7f5.html