【问题标题】:BufferedOutputStream concatenates two sequential flush() callsBufferedOutputStream 连接两个连续的 flush() 调用
【发布时间】:2023-03-06 06:47:01
【问题描述】:

我想使用 BufferedOutputStream 发送单独的消息。所以我做bos.write(msg1); bos.flush(); bos.write(msg2); bos.flush()。另一方面,我有一个 BufferedReader,它依赖于这些消息的分离:

BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream()));
InputStream is = server.getInputStream();
while (true) {
    if (br.ready()) {
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
    }
}

但我得到的是这样的: “向客户端发送 30 个字节;向客户端发送 30 个字节”,另一端:“收到 60 个字节”。

【问题讨论】:

  • 没有必要连接flush()。只需在发送数据的代码末尾调用此方法即可。

标签: java flush bufferedoutputstream


【解决方案1】:

这帮助我解决了我的问题:http://www.codeproject.com/Articles/11922/Solution-for-TCP-IP-client-socket-message-boundary

我现在基本上做的是首先检查有效负载长度并使用它来确定消息边界。之后我可以继续处理其他消息。

【讨论】:

    【解决方案2】:

    您提到的行为来自TCP,而不是来自BufferedOutputStream,原因是TCP中没有消息这样的东西,因此不能保证写入大小和读取大小之间的任何对应关系。它是一个字节流协议。如果您需要消息边界,您必须自己提供。

    您也不应该以这种方式使用ready()available()。只需使用固定大小的缓冲区,然后阻塞即可。

    【讨论】:

    • 感谢您的回答。我了解这个问题,但我仍在努力寻找解决此问题的好方法。我想将任意长度的字符串封装在 WebSocket 帧中,然后使用 BufferedOutputStream 将其发送过来。你还会推荐使用固定大小的缓冲区吗?我如何确保使用固定大小的缓冲区获得正确的边界?
    • 实现消息的方式有很多种。 1. 每条消息的长度相同。 2. 一个长字前缀。 3.类型-长度-值。 4. 像 XML 这样的自描述协议。 5. XDR、ASN.1、BER 等已编译协议...您可以使用任何具有固定大小字节数组缓冲区的协议。
    猜你喜欢
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多