JAVA NIO服务器 - 未接收客户端空白消息/部分消息

时间:2018-06-17 06:05:30

标签: java server nio

我使用带有服务器套接字通道和套接字通道的NIO包构建了一个服务器和客户端。基本设置有效。但是当我尝试使用执行程序服务移动我的代码处理单独线程中的每个连接时,我开始得到奇怪的错误,我收到部分消息或有时是空白消息。

这是我的代码,我将选择密钥传递给具有执行服务的线程

private void readAndRespond(SelectionKey selectionKey) {
    this.executorService.submit(new Worker(selectionKey));
}

private class Worker implements Runnable {
    private SelectionKey selectionKey;

    private Worker(SelectionKey selectionKey) {
        this.selectionKey = selectionKey;
    }

    @Override
    public void run() {
        SocketChannel socketChannel;
        ArrayList<ByteBuffer> buffers;
        String data, reply;
        ByteBuffer responseBuffer;

        socketChannel = (SocketChannel) selectionKey.channel();

        try {
            buffers = this.readRequest(socketChannel);
            data = this.extractData(buffers);

            if (!data.isEmpty()) {
                reply = responseManager.reply(data);
                responseBuffer = ByteBuffer.wrap(reply.getBytes());
                socketChannel.write(responseBuffer);
            }
        }
        catch (IOException e) {
            System.out.println("Unable to process response " + e.getMessage());
        }
    }

    private ArrayList<ByteBuffer> readRequest(SocketChannel socketChannel) throws IOException {
        int counter;
        ByteBuffer current;
        ArrayList<ByteBuffer> buffers;

        counter = 2;
        buffers = new ArrayList<>();
        current = ByteBuffer.allocate(minBuffer);
        buffers.add(current);

        while (socketChannel.read(current) > 0) {
            if (!current.hasRemaining()) {
                current = ByteBuffer.allocate(minBuffer * 2 * counter);
                buffers.add(current);
                counter++;
            }
        }

        return buffers;
    }

    private String extractData(ArrayList<ByteBuffer> buffers) throws UnsupportedEncodingException {
        StringBuilder stringBuilder;

        stringBuilder = new StringBuilder();
        for(ByteBuffer buffer : buffers) {
            stringBuilder.append(new String(buffer.array(), "UTF-8"));
        }

        return stringBuilder.toString().trim();
    }
}

1 个答案:

答案 0 :(得分:0)

在交给线程阅读之前需要添加此内容

selectionKey.interestOps( selectionKey.interestOps() & ~SelectionKey.OP_READ );