2015-07-24 4 views
0

Ошибка при получении данных с сервера (только строка данных).NSInputStream не получает все данные

для примера
сервер послал данные (15000bytes)
мой iPhone полученных данных (7878bytes)

поэтому я стараюсь искать и я знаю, в то время как метод ответа.

, но я не могу применить мой код ..

Я думаю NSMutableData это намек ..

как сделать ..

Вот мой код.

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { 

NSLog(@"stream event %lu", (unsigned long)streamEvent); 

switch (streamEvent) { 

    case NSStreamEventOpenCompleted: 
     NSLog(@"Stream opened"); 

     if(_connectServer) 
     { 
      [_connectServer invalidate]; 
      _connectServer = nil; 
     } 

     break; 
    case NSStreamEventHasBytesAvailable: 

     if (theStream == inputStream) 
     { 
      if(!_serverOpen) 
      { 
       uint8_t buffer[1024]; 

       int len; 

       while ([inputStream hasBytesAvailable]) 
       { 
        len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 

        if (len > 0) 
        { 
         NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 

         if (nil != output) 
         { 

          [self receivedServerData:output]; 

          if(!_serverOpen) 
          { 
           [self initNetworkCommunicationWithIpPort:output]; 
          } 

         } 
        } 
       } 
      } 

      else 
      { 
       uint8_t buffer[20]; 

       int len; 

       while ([inputStream hasBytesAvailable]) 
       { 
        len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 

        NSString* strBuffer = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 
        NSLog(@"STRBUFFER %@", strBuffer); 

        strBuffer = [strBuffer substringFromIndex:7]; 

        uint8_t dataBuffer[[strBuffer intValue]]; 

        NSLog(@"databuffer %lu", sizeof(dataBuffer)); 

        int lenBuffer = [inputStream read:dataBuffer maxLength:sizeof(dataBuffer)]; 

        NSLog(@"lenBuffer %d", lenBuffer); 

        int position = 0 ; 

        if (lenBuffer > 0) 
        { 
         NSString *output = [[NSString alloc] initWithBytes:dataBuffer length:lenBuffer encoding:NSUTF8StringEncoding]; 

         if (nil != output) 
         { 
          [self receivedServerData:output]; 

          if(!_serverOpen) 
          { 
           [self initNetworkCommunicationWithIpPort:output]; 
          } 
         } 
        } 
       } 
      } 
     } 
     else 
     { 
      NSLog(@"333"); 
     } 
     break; 

    case NSStreamEventHasSpaceAvailable: 
    { 
    } 
     break; 

    case NSStreamEventErrorOccurred: 
     NSLog(@"Can not connect to the host!"); 
     _serverOpen = NO; 

     break; 

    case NSStreamEventEndEncountered: 
     [theStream close]; 
     [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     theStream = nil; 

     break; 
    default: 
     NSLog(@"Unknown event"); 
} 
} 
+0

Добавьте код для метода: 'receivedServerData'. – zaph

+0

Используете ли вы какой-либо метод для сериализации данных. Например: google protocolbuffer, zlib, ... –

ответ

0

Если у вас есть доступ к серверу, который посылает данные, самый простой способ сделать это было бы сделать первые 4 байта int который представляет длину данных. Затем вы анализируете первые 4 байта в данных и читаете длину. Затем, когда у вас есть длина, когда есть свободное место на входном потоке, добавьте байты в свойство NSMutableData, пока у получателя не будет length, который вы получили в начале. Как только это произойдет, сразу преобразуйте его в строку. Из-за проблем с задержкой в ​​сети вы не можете быть уверены, что все данные будут получены в потоке сразу.

+0

Длина должна быть в заголовке, поле Content-Length entity-header указывает размер тела объекта. – zaph

1

Поскольку @Manav утверждает, что вы можете ожидать получения потока в нескольких кусках, просто добавьте их в NSMutableData, пока не получите NSStreamEventEndEncountered.

Смежные вопросы