1

I want to send separate messages using a BufferedOutputStream. So I do bos.write(msg1); bos.flush(); bos.write(msg2); bos.flush(). On the other end, I have a BufferedReader which relies on separation of these messages:

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);
    }
}

But what I get is something like this: "Sending 30 bytes to client; Sending 30 bytes to client" and on the other end: "Received 60 bytes".

user2974705
  • 43
  • 1
  • 5
  • it is unnecessary to concatenate flush(). just call this method at the end of your code that sends the data. – Kachna Jul 18 '15 at 20:30

2 Answers2

2

The behaviour you mention comes from TCP, not from BufferedOutputStream, and the reason is that there is no such thing as a message in TCP, and therefore no guaranteee of any correspondence between write sizes and read sizes. It is a byte-stream protocol. If you want message boundaries you must provide them yourself.

You should not use ready() and available() in that way either. Just use a fixed-size buffer, and block.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Thanks for your answer. I understand the problem, but I'm still trying to find a nice way to fix this. I want to encapsulate strings of arbitrary length in a WebSocket frame and then send it over, using the BufferedOutputStream. Would you still recommend to use fixed-size buffers? How will I make sure I get the boundaries right with fixed-size buffers? – user2974705 Jul 19 '15 at 11:42
  • There are numerous ways to implement messages. 1. Every message the same length. 2. A length-word prefix. 3. Type-length-value. 4. Self-describing protocols like XML. 5. Compiled protocols like XDR, ASN.1, BER, ... You can use any of those with fixed-sized byte array buffers. – user207421 Jul 19 '15 at 22:58
0

This helped me solving my problem: http://www.codeproject.com/Articles/11922/Solution-for-TCP-IP-client-socket-message-boundary

What I basically do now is checking the payload length first and using this I determine the message boundary. Afterwards I can continue with the other messages.

user2974705
  • 43
  • 1
  • 5