【问题标题】:Java Partial message handling from socket NIO ByteBuffer来自套接字 NIO ByteBuffer 的 Java 部分消息处理
【发布时间】:2016-05-04 17:32:37
【问题描述】:

我有一个存储多条消息的缓冲区。假设缓冲区是 50 字节(让我尝试用元代码来说明这一点)

-------------------- (50 byte empty buffer)

我的消息大小为 20。在给定的套接字读取中,我可能会收到 1 条消息

 |111111111|-----------  (50 byte buffer with 1 20 byte message

或两条消息

 |111111111|222222222|----

但如果我收到三条消息,我最终会收到部分第三条消息

 |111111111|222222222|3333 (TRUNCATE)

在下一个 socketread 时,第三条消息的其余部分通过,字节流包含消息 3 的后半部分:

>>> socket.read() 
33334444444455555555 ....

此外,我知道第三条消息的开始位置,所以我想简单地将第三条消息的内容保留在我的缓冲区中。我认为做紧凑会是这样:

>>> readbuffer.compact()

然后简单地将同一个缓冲区传回 socket.read()

>>> socket.read(readBuffer)

理想情况下,这会填满我的缓冲区

33333333|44444444|55555...

但是,我不认为压缩并将 readbuffer 简单地传递回 sock.read() 是正确的方法。

是否有一种众所周知的解决方案可以以这种方式处理部分消息?我可以想到很多可以尝试的东西,但这必须是一个普遍的问题。我想尽可能避免中间创建缓冲区,但想不出不调用某种剩余缓冲区的解决方案。

谢谢

【问题讨论】:

  • 是什么让您认为compact() 不是正确的方法?是的。
  • 我尝试在下一次 socket.read() 调用后打印字节数组,但我认为 socket.read() 不会在缓冲区的位置开始写入。 IE,如果我的最后一个位置是P,那么对socket.read()的调用是从P开始还是从0开始?
  • 它从 P 开始,就像 Javadoc 一样。读取与放置相同。
  • 谢谢。 Derp,我现在看到了(假设读取了一个长度为 n 的字节序列,其中 0
  • 你能举一些例子吗?我尝试从套接字读取,然后在我的第一个数据包完成后应用紧凑 api,该数据包为 275 字节,缓冲区大小为 512,但不幸的是我的位置保持不变。创建状态机以在移动到下一个之前验证数据包。 var bytesRead = mUart.read(bb.array(), bb.capacity())

标签: java sockets buffer bytearray bytebuffer


【解决方案1】:

你错了。使用compact(),然后为下一个read() 重用缓冲区正是正确的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多