0

我的目标是从客户端向服务器发送不同类型的消息,它将是基于文本的。我不确定的是如何在这里删除部分读取。我必须确保我得到一个完整的信息,仅此而已。

有没有人有这方面的经验?

这是我到目前为止所拥有的:

    private void handleNewClientMessage(SelectionKey key) throws IOException {
    SocketChannel sendingChannel = (SocketChannel) key.channel();

    ByteBuffer receivingBuffer = ByteBuffer.allocate(2048);
    int bytesRead = sendingChannel.read(receivingBuffer);
    if (bytesRead > 0) {
        receivingBuffer.flip();

        byte[] array = new byte[receivingBuffer.limit()];
        receivingBuffer.get(array);
        String message = new String(array);

        System.out.println("Server received "  +message);           
    }
    selector.wakeup();
}

但是我没有办法“结束”这条信息,并且一定会收到一条完整的信息。

最好的问候,

4

1 回答 1

3

除非您一次只读取一个字节,否则您永远无法确定您不会阅读超过一条消息。(我不建议这样做)。

相反,我会尽可能多地读入 ByteBuffer,然后解析它以找到消息的结尾,例如文本的换行符。

当您找到行尾时,将其提取并将其转换为字符串并进行处理。重复直到你有部分消息(或什么都没有)

如果你发现你只有消息的一部分,当你有时你 compact() (如果 position() > 0) 并尝试 read() 更多。

这将允许您一次阅读尽可能多的消息,但也可以处理不完整的消息。

注意:您需要保留 ByteBuffer 以进行连接,以便知道您之前阅读过哪些部分消息。

注意:如果您的消息大于缓冲区大小,这将不起作用。我建议使用 1+ MB 的回收直接 ByteBuffer。使用直接 ByteBuffers,只有使用的 ByteBuffer 页面被分配给实际内存。

如果您担心性能,我会在可能的情况下重新使用您byte[]的。如果您需要的空间比已有的更多,您只需要重新分配它。

顺便说一句,您可能会发现使用带有普通 IO 的 BufferedReader 使用起来要简单得多,但性能仍然足够好。

于 2013-04-25T14:36:56.357 回答