如何使用socketchannel提高以下代码的性能?我怎样才能收到UTF8字符串?

时间:2015-09-08 13:12:23

标签: java bytebuffer socketchannel

这是重要的代码:

public void setSelector() {
    try {

        this.writebuf.clear();
        this.selector = Selector.open();
        int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
        SelectionKey selectionKey = this.socketChannel.register(selector, interestSet);


        // Checking if the buffer is in write mode
        if (!(this.writebuf.limit() == this.writebuf.capacity())) {
            writebuf.flip();
        }

        int bytesRead = 0;

        while (selector.select() > -1) {

            // Wait for an event one of the registered channels

            // Iterate over the set of keys for which events are available
            Iterator selectedKeys = selector.selectedKeys().iterator();
            while (selectedKeys.hasNext()) {
                SelectionKey key = (SelectionKey) selectedKeys.next();
                selectedKeys.remove();
                if (!key.isValid()) {
                    continue;
                }
                if (key.isReadable()) {

                    bytesRead = this.socketChannel.read(this.writebuf);

                    if (bytesRead > 0 && writebuf.hasRemaining()) {
                        this.writebuf.flip();
                        this.parseSubtitleMessage(new String(writebuf.array(), charset));
                        this.writebuf.clear();
                        this.writebuf.flip();
                    }
                }
                if (key.isWritable()) {
                // Not yet implemented
                }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }
}

Socketchannel设置为nonblocking模式。 第一个问题是while循环会产生巨大的工作量。基本上我需要在pauseREAD WRITE出现之前event代码的内容。 另一个有问题的部分是此代码:

this.parseSubtitleMessage(new String(writebuf.array(), charset));

我知道当我调用array()方法时,即使我调用forgotten方法,我也会从前一条消息中获取整个缓冲区,包括一些clear个字节。我找到了一个使用while循环迭代单个字节的解决方案,直到buffer.hasRemaining()设置为false。但在这种情况下我不知道如何使用指定的字符集。

编辑: 我解决了我的“无限循环”问题,这里是固定代码:

public void runSelector() {
    try {

        this.writebuf.clear();

        // Checking if the buffer is in write mode
        if (!(this.writebuf.limit() == this.writebuf.capacity())) {
            writebuf.flip();
        }

        this.selector = Selector.open();

        int interestSet_RW = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

        int bytesRead = 0;

        SelectionKey selectionKey = this.socketChannel.register(selector, SelectionKey.OP_READ);

        while(true) {

            int readyChannels = selector.select();

            if(readyChannels == 0) continue;


            Set<SelectionKey> selectedKeys = selector.selectedKeys();

            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

            while(keyIterator.hasNext()) {

                SelectionKey key = keyIterator.next();

                if (!key.isValid()) {
                    continue;
                }

                // Check if there's something to write in the queue and change interestops apropriately.
                if (monitorObject.tosendIsEmpty()) {
                    selectionKey.interestOps(SelectionKey.OP_READ);
                } else {
                    selectionKey.interestOps(interestSet_RW);
                }

                if (key.isWritable()) {
                }

                if (key.isReadable()) {
                    bytesRead = this.socketChannel.read(this.writebuf);

                    if (bytesRead > 0 && writebuf.hasRemaining()) {
                        this.parseSubtitleMessage(new String(this.writebuf.array(), charset));
                        this.writebuf.clear();
                    }
                }
                keyIterator.remove();
            }
        }




    } catch (IOException e) {
        e.printStackTrace();
    }
}

我无意中创建了一个重复的线程。那天我的谷歌技能可能非常糟糕。 然而,第二个问题仍然存在,我将非常感谢你的帮助。感谢

编辑2:所以我也解决了第二个问题。这是代码:

                if (key.isReadable()) {

                    bytesRead = this.socketChannel.read(this.writebuf);

                    bytes = new byte[bytesRead];

                    int x = 0;

                    this.writebuf.flip();

                    while(this.writebuf.hasRemaining()) {
                        bytes[x] = this.writebuf.get();
                        x++;
                    }

                    System.out.println(new String(bytes, charset));

                    this.writebuf.flip();
                    this.writebuf.clear();
                }

0 个答案:

没有答案