我的目标是将不同类型的消息从客户端发送到服务器,它将是基于文本的。我不确定的是如何在这里使用部分读取。我必须确保我得到的是一个完整的消息,而不是更多。
有谁有这方面的经验吗?
这是我到目前为止所知道的:
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();
}但我没有办法“结束”这条消息,并确保有一条完整的消息。
致以最好的问候,O
发布于 2013-04-25 22:36:56
除非你一次只读一个字节,否则你永远不能确定你不会读一条以上的消息。(我不建议这样做)。
相反,我会尽可能多地读入ByteBuffer,然后解析它以找到消息的结尾,例如文本的换行符。
找到行尾时,提取它并将其转换为字符串并对其进行处理。重复以上步骤,直到得到部分消息(或者什么都没有留下)
如果你发现你只有一条消息的一部分,你可以压缩()(如果position() > 0),然后尝试再读一些()。
这将允许您一次读取尽可能多的消息,但也可以处理不完整的消息。
注意:您需要保留连接的ByteBuffer,这样您才能知道您以前读过哪些部分消息。
注意:如果您的消息大于您的缓冲区大小,这将不起作用。我建议使用回收的直接ByteBuffer,比如说1+ MB。使用直接ByteBuffers时,只将ByteBuffer中使用的页面分配给实际内存。
如果你关心性能,我会尽可能重用你的byte[]。只有在需要比已有空间更多的空间时,才需要重新分配它。
顺便说一句,您可能会发现将BufferedReader与普通IO一起使用要简单得多,但性能仍然足够好。
https://stackoverflow.com/questions/16217579
复制相似问题