1

I'm using Java Socket Programming in order to receive server responses, I'm using a char array and read each response in it using read() method:

InputStream stream = null;
try{
    stream = socket.getInputStream();
}catch(Exception e){
    conn_lost();
}

if(stream != null){
    input = new BufferedReader(new InputStreamReader(
                    stream));

Looper.prepare();
char a[] = new char[1000];
for(int i =0; i < a.length; i++){
      a[i] = ' ';
   }

while (true){

   input.read(a);

   String response = String.valueOf(a);

   process_server_response(response);

   for(int i =0; i < a.length; i++){
         a[i] = ' ';
      }
}

The problem is some times I can't receive the full response from the server and instead of that I receive like half of it and then the response after that I receive the other half.

Worth to mention:

1- the affected response is a little large that other responses but I'm sure it's not exceed 1000 litters.

2- I'm pretty sure the server-side works perfectly and it sends the responses completed.

3- there isn't any type of terminators exist which could cause that behavior.

amenthes
  • 3,117
  • 1
  • 32
  • 38
Muhammed Refaat
  • 8,914
  • 14
  • 83
  • 118
  • 1
    You needn't fill the buffer (`a`) with spaces. `input.read(a)` returns the number of `char`s that were read. If you save this number to a variable, you can use [`String.valueOf(char[], int, int)`](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#valueOf-char:A-int-int-) to convert the buffer data to a string. That should increase performance. – fabian Jul 01 '14 at 12:33
  • @fabian well, thanks a lot, that really was bothering me and I didn't think before about using the retrieved number of chars. cheers. – Muhammed Refaat Jul 01 '14 at 12:35

1 Answers1

2

The problem is some times I can't receive the full response from the server and instead of that I receive like half of it and then the response after that I receive the other half.

Yes. That's how stream protocols work. You shouldn't assume that you'll receive all the data in a single call to read().

If you have multiple messages on the same stream, you'll need a way of telling where a message ends. You must not rely on read() reading the whole of one message but not reading any of the next message.

The three common approaches are:

  • A length prefix for each message
  • A separator between messages
  • Self-terminating messages (e.g. XML, where you can tell the end of a document by reaching its closing tag)

If you don't have any of those schemes in place, but you want to put multiple messages on the wire and process them separately, your protocol is fundamentally broken and you should revisit it.

Additionally, you should specify the encoding to apply when constructing the InputStreamReader. Don't just use the platform default.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • by the way, in your opinion what's the best encoding to apply when I receive Json responses? – Muhammed Refaat Jul 02 '14 at 08:46
  • 1
    @MuhammedRefaat: Well, if you're able to work in a binary format with the text within it, I'd UTF-8 encode the JSON, and have a simple length prefix. I'm a big fan of length prefixes, in terms of letting the client know exactly how much data to read, without it depending on the content. It does depend on you controlling both the client and the server though. – Jon Skeet Jul 02 '14 at 08:51