title: Parsing data after sending between iOS devices over NSStream
body: <p>I have an application set up to send data between two iOS devices using <code>NSStream</code>s over a TCP connection.</p>
  <p>The data sent consists of two parts:</p>
  <ol>
  <li>An integer indicating the size of the message object to come</li>
  <li>The message object, some <code>NSStrings</code> and an <code>NSData</code> object encoded with NSKeyedArchiver</li>
  </ol>
  <p>The issue:</p>
  <ol>
  <li>When the NSData object is around 1.5Mb, I get an incomprehensible archive exception when I try to decode it. When reading the 4 bytes following where the message should be, a large number is there, not the size of the next message.</li>
  <li>When the NSData object is around 80Kb, two messages are successfully decoded and then I get the incomprehensible archive exception.</li>
  </ol>
  <p>It seems like the data is getting out of order at some point... though the whole purpose of TCP is to keep it in order. So, I must be the problem!</p>
  <h2>Relevant Code</h2>
  <h3>Server</h3>
  <p><code>sendData:</code> is passed the Message object that has been encoded with an NSKeyedArchiver. It is called for 100ish messages in a short period of time</p>
  <pre><code>// dataQueue is an NSMutableArray
  - (void) sendData:(NSData *)data
  {
    int size = data.length;
    NSData *msgSize = [NSData dataWithBytes:&amp;size length:sizeof(int)];
    
    if (self.outputStream.hasSpaceAvailable &amp;&amp; (self.dataQueue.count == 0)) {
      [self.dataQueue addObject:data];
      [self.outputStream write:msgSize.bytes maxLength:msgSize.length];
    }
    else {
      [self.dataQueue addObject:msgSize];
      [self.dataQueue addObject:data];
    }
  }
  
  //called by NSStreamDelegate method when space is available
  - (void) hasSpaceAvailable
  {
    if (self.dataQueue.count &gt; 0) {
      NSData *tmp = [self.dataQueue objectAtIndex:0];
      [self.outputStream write:tmp.bytes maxLength:tmp.length];
      [self.dataQueue removeObjectAtIndex:0];
    }
  }
  </code></pre>
  <h3>Client</h3>
  <p><code>streamHasBytes:</code> collects the message fragments and appends them to self.buffer. When the length of self.buffer becomes greater than the message length indicated in the first 4 bytes of self.buffer, the Message object is parsed...</p>
  <pre><code>//Called by NSStreamDelegate method when bytes are available
  - (void) streamHasBytes:(NSInputStream *)stream
  {
    NSInteger       bytesRead;
    uint8_t         buffer[32768];
    
    bytesRead= [stream read:buffer maxLength:sizeof(buffer)];
    
    if (bytesRead == -1 || bytesRead == 0) //...err
    
    @synchronized(self) { //added to test concurrency
    [self.buffer appendBytes:buffer length:bytesRead];
    }
    [self checkForMessage];
  }
  
  - (void) checkForMessage
  {
    @synchronized(self) { //added to test concurrency
    int msgLength = *(const int *)self.buffer.bytes;
          
    if (self.buffer.length &lt; msgLength) return;
    
    //remove the integer from self.buffer
    [self.buffer replaceBytesInRange:NSMakeRange(0, sizeof(int)) withBytes:NULL length:0]; 
    
    //copy the actual message from self.buffer
    NSData *msgData = [NSData dataWithBytes:self.buffer.bytes length:msgLength];
          
    //remove the message from self.buffer
    [self.buffer replaceBytesInRange:NSMakeRange(0, msgLength) withBytes:NULL length:0];
                                    
    Message *theMsg = [NSKeyedUnarchiver unarchiveObjectWithData:msgData];
    [self.delegate didReceiveMessage:theMsg];
    }
  }
  </code></pre>
  <h1>EDIT:</h1>
  <p>I'm now noticing that, in the case where the NSData object in the first Message is around 1.5Mb, for a total Message size of about 1.6Mb, only about 1.3Mb are received by the client...  This would explain the incomprehensible archive errors. Why would all of the data not be delivered?</p>