iOS - получение двоичных данных с сервера работает только в режиме отладки
У меня есть вопрос относительно моего последнего поста
Но я думаю, что сначала я должен предоставить код:
Это функция для обработки моего созданного объекта
- (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;
}
}
А я вот получаю данные из потока
- (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;
}
Все отлично работает с симулятором или если я отлаживаю приложение на iPhone, но если я пытаюсь запустить его на устройстве, я всегда получаю BAD_EXCESS, потому что значение packetLength неверно, и поэтому я пытаюсь прочитать слишком много байтов в свой буфер.
Теперь на мой вопрос: как может быть, чтобы все значения были правильными в режиме отладки, но полностью запутались в режиме выполнения? Есть ли что-нибудь, что я мог бы избежать этой проблемы, или я должен знать?
Ваша помощь очень ценится
Вот моя функция BytesToInt, но я думаю, что она работает как надо, если полученные значения верны
- (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;
}
2 ответа
Я, наконец, сделал это путем зацикливания полученных данных, пока не достиг своего значения maxLength. Это было не так сложно исправить, но я не был достаточно умным...
Ну вот как я это сделал:
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];
}
Проверьте возвращаемое значение вашего [NSInputStream read]
, Указание maxLength не означает, что на самом деле столько байтов будет действительно прочитано. Это может быть меньше или даже 0. Если поток читает только 2 байта, я думаю, вам придется выполнить второе чтение с указателем, который указывает за байтами, уже прочитанными в вашем буфере, и с maxLength оставшихся байтов в буфер.