Search code examples
iphoneiosdebuggingnsstream

iOS - receiving binary data from server only works in debug mode


I have a question concerning my last post

But I think at first I should provide some code:

This is the function to handle my created object

- (void)handleObject:(NSMutableData *)object {

NSLog(@"[object length] = %d", [object length]);
Byte *byteArray;
byteArray = (Byte *)[object bytes];

switch (byteArray[5]) {

    case 0: NSLog(@"Login OK"); 
        break;

    case 1: NSLog(@"Exit. Server disconnect");
        break;

    case 2: NSLog(@"Ping erhalten");
        break;

    case 4: NSLog(@"Points received");
        break;

    case 6: NSLog(@"transfer of POLYLINE vector objects");
        break;

    case 8: NSLog(@"transfer of POLYGON vector objects");
        break;

    case 9: NSLog(@"transfer of Render Rule");
        break;

    case 10: {

        NSLog(@"end of response for RequestVectorObjects");                                 
        isLoading = FALSE;
    }
        break;

    case 11: NSLog(@"Background Colorcode: %d", (byteArray[6] & 0xFF));
        break;    

    default: NSLog(@"From server: default value");
        break;
}

}

And I here I receive the data from a stream

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {

switch(eventCode) {

    case NSStreamEventHasBytesAvailable:
    {
        isLoading = YES; 

        while (isLoading) {               

            uint8_t bufSize[4];            

            int packetLength = 0; 

            [(NSInputStream *)stream read:bufSize maxLength:4];
            packetLength = [self bytesToInt:bufSize withOffset:0];
            NSLog(@"packetLength: %d", packetLength);

            [tempStore appendBytes:bufSize length:4];

            if (packetLength == 25600) {

                loggedIn = YES;
                uint8_t buf[4];
                [(NSInputStream *)stream read:buf maxLength:4];
                [tempStore appendBytes:buf length:4];
                [self handleObject:tempStore];
            }
            else {

                uint8_t buf[packetLength];
                [(NSInputStream *)stream read:buf maxLength:packetLength];
                [tempStore appendBytes:buf length:packetLength];
                [self handleObject:tempStore];                    
            }
            [tempStore resetBytesInRange:NSMakeRange(0, [tempStore length])];
            [tempStore setLength:0];
        }           
        NSLog(@"Finished loading objects");                 

    } break;      

}

It all works just fine with the simulator or if I debug the application on the iPhone, but if try to run it on the device I always get BAD_EXCESS, because the value of packetLength is wrong and so I try to read too much byte into my buffer.

Now to my question: How can it be that all values are right in debug mode, but get totally messed up in run mode? Is there anything I could to avoid that problem or I should be aware of?

Your help is much appreciated

Here is my BytesToInt Function, but I think it works as it should, if the received values are correct

- (int)bytesToInt:(Byte *)b withOffset:(int)offset {

int ret = 0;
for (int i = 0; i < 4; i++) {

    ret |= (b[offset + i] & 0xFF) << (3-i)*8;
}    
return ret;

}


Solution

  • I finally did it by looping the received data until I reached my maxLength value. It wasn't too hard to fix, but I wasn't acting quite smart...

    Well, here is how I did it:

    isLoading = YES; 
    
            while (isLoading) {               
    
                uint8_t bufSize[4];            
    
                int packetLength , maxLength, len;
    
                maxLength = 4;
                len = [(NSInputStream *)stream read:bufSize maxLength:maxLength];
                NSLog(@"len = %d", len);
                packetLength = [self bytesToInt:bufSize withOffset:0];
                NSLog(@"packetLength: %d", packetLength);
    
                [tempStore appendBytes:bufSize length:maxLength];
    
                if (packetLength == 25600) {
    
                    loggedIn = YES;
                    maxLength = 4;
                    uint8_t buf[maxLength];                    
                    len = [(NSInputStream *)stream read:buf maxLength:maxLength];
                    NSLog(@"len = %d", len);
                    [tempStore appendBytes:buf length:maxLength];
                }
                else {
                    maxLength = packetLength;
                    BOOL allDataReceived = NO;
    
                    while (!allDataReceived) {
    
                        uint8_t buf[maxLength];                    
                        len = [(NSInputStream *)stream read:buf maxLength:maxLength];                                                                    
                        NSLog(@"len = %d", len);                       
    
                        if (len < maxLength) {
    
                            maxLength -= len;
                            [tempStore appendBytes:buf length:len];
                        }
                        else {
    
                            allDataReceived = YES;
                            [tempStore appendBytes:buf length:len];
                        }                            
                    }                    
                }
                [self handleObject:tempStore];
                [tempStore resetBytesInRange:NSMakeRange(0, [tempStore length])];
                [tempStore setLength:0];
            }