title: Socket using BufferedOutputStream/BufferedInputStream receives bogus data random
body: <p>I have a client/server application that sends/receives data using <code>BufferedOutputStream / BufferedInputStream</code> . The protocol of communication is the following:</p>
  
  <ol>
  <li><p>Send part :</p>
  
  <ul>
  <li>first byte is the action to perform </li>
  <li>next 4 bytes are the length of the message </li>
  <li>next x bytes (x=length of message) are the message itself </li>
  </ul></li>
  <li><p>Receive part : </p>
  
  <ul>
  <li>read first byte to get the action</li>
  <li>read the next 4 bytes to get the message length </li>
  <li>read the x (obtained on prev step) bytes to get the message      </li>
  </ul></li>
  </ol>
  
  <p>Now the problem is that <strong>sometimes</strong> when i sent the length of the message (ex : 23045) on server part when i receive it i get a huge int (ex: 123106847).   </p>
  
  <p>A important clue is that this happens <strong>only</strong> when message exceeds a number of characters  (in my case > 10K ) , if i sent a smaller message (ex 4-5k) everything works as expected.</p>
  
  <p>Client send part (outputStream/inputStream are the type BufferedXXXStream):</p>
  
  <pre><code>    private String getResponseFromServer( NormalizerActionEnum action, String message) throws IOException{
  
          writeByte( action.id());
          writeString( message);
          flush(;
  
          return read();
      }
  
      private String read() throws IOException{
          byte[] msgLen = new byte[4];
          inputStream.read(msgLen);
          int len = ByteBuffer.wrap(msgLen).getInt();
          byte[] bytes = new byte[len];
          inputStream.read(bytes);
  
          return new String(bytes);
      }
  
      private void writeByte( byte msg) throws IOException{
          outputStream.write(msg);
      }
  
      private void writeString( String msg) throws IOException{
  
          byte[] msgLen = ByteBuffer.allocate(4).putInt(msg.length()).array();
  
          outputStream.write(msgLen);
          outputStream.write(msg.getBytes());
      }
  
      private void flush() throws IOException{
          outputStream.flush();
      }
  </code></pre>
  
  <p>Server part (_input/_output are the type BufferedXXXStream)</p>
  
  <pre><code>private byte readByte() throws IOException, InterruptedException {
      int b =  _input.read();
      while(b==-1){
          Thread.sleep(1);
          b = _input.read();
      }
  
      return (byte) b;
  }
  
  private String readString() throws IOException, InterruptedException {
      byte[] msgLen = new byte[4];
      int s = _input.read(msgLen);
      while(s==-1){
          Thread.sleep(1);
          s = _input.read(msgLen);
      }   
  
      int len = ByteBuffer.wrap(msgLen).getInt();     
      byte[] bytes = new byte[len];
      s = _input.read(bytes);
      while(s==-1){
          Thread.sleep(1);
          s = _input.read(bytes);
      }
  
      return new String(bytes);
  }
  
  private void writeString(String message) throws IOException {
      byte[] msgLen = ByteBuffer.allocate(4).putInt(message.length()).array();
      _output.write(msgLen);
      _output.write(message.getBytes());
      _output.flush();
  }
  
  ....
  
  byte cmd = readByte();
  String message = readString();
  </code></pre>
  
  <p>Any help will be greatly appreciated. If you need additional details let me know.  </p>
  
  <p><strong>UPDATE:</strong> Due to comments from <strong><em>Jon Skeet</em></strong> and <strong><em>EJP</em></strong> i realized that the read part on the server was having some pointless operations but letting this aside i finally got what the problem was: the key thing is that i keep the streams opened for the full length of the app and the first several times i sent the message length i'm able to read it on the server side BUT as <strong><em>Jon Skeet</em></strong> pointed out the data doesn't arrive all at once so when i try to read the message length again i'm actually reading from the message itself that is why i have bogus message lengths .</p>
  
  <p>~ instead of sending the data length and then reading it all at once i sent it without the length and i read one byte at a time till the end of the string which works perfectly</p>
  
  <pre><code>private String readString() throws IOException, InterruptedException {
      StringBuilder sb = new StringBuilder();
      byte[] bytes = new byte[100];
      int s = 0;
      int index=0;
      while(true){
          s = _input.read();
          if(s == 10){
              break;
          }
          bytes[index++] = (byte) (s);
          if(index == bytes.length){
              sb.append(new String(bytes));
              bytes = new byte[100];
              index=0;
          }           
      }
      if(index &gt; 0){
          sb.append(new String(Arrays.copyOfRange(bytes, 0, index)));
      }
  
      return sb.toString();
  }
  </code></pre>