2016-06-17 49 views
1

檢索NSData的對象,所以我的應用程序沿着這些線路的工作原理:如何可靠地NSInputStream XCode中

  1. 一個iPod不斷地發送包含NSDictionaries:在JPEG和一些圖像特性NSString的編碼圖像。
  2. NSDictionary使用NSPropertyListSerialization格式BinaryFormat_v1_0進行編碼,並通過NSStream以1024字節的數據包的形式發送到在OSX上運行應用程序的中央計算機。
  3. OSX應用程序接收數據包,不斷附加到單個NSMutableData對象,直到它看到下一個NSData對象的第一個數據包(以我發現的二進制格式開始爲'bplist')。
  4. 通過調用NSPropertyListSerialization,NSData被轉換回OSD應用程序使用的NSDictionary。
  5. 一旦NSData成功轉換(或不成功),NSData對象被設置回零以開始讀取下一輪數據包。

還有一些注意事項:NSInputStream和NSOutput流都在NSDefaultRunLoopMode的各自設備的currentRunLoop上運行。

當運行這個過程中,有時會轉換回NSDictionary中工作正常,沒有錯誤(約嘗試的1/3),但其他時間轉換返回此錯誤:

Error: Failed to convert NSData to NSDict : Error Domain=NSCocoaErrorDomain Code=3840 "Unexpected character b at line 1" UserInfo={NSDebugDescription=Unexpected character b at line 1, kCFPropertyListOldStyleParsingError=Error Domain=NSCocoaErrorDomain Code=3840 "Conversion of string failed." UserInfo={NSDebugDescription=Conversion of string failed.}}

以下是

...的方法來處理流事件:

-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { 
switch(eventCode) { 
    case NSStreamEventHasBytesAvailable: { 

     uint8_t buf[1024]; 
     unsigned int len = (unsigned)[(NSInputStream *)aStream read:buf maxLength:1024]; 

     if(len) { 
      [self handleEventBuffer:buf WithLength:len]; 
     } 
... 

...和服用方法是從流分析數據的程序部分保健數據:

-(void)handleEventBuffer:(uint8_t*)buf WithLength:(unsigned int)len { 
... 
NSString *bufStr = [NSString stringWithFormat:@"%s",(const char*)buf]; 
     if ([bufStr containsString:@"bplist00"] && [self.cameraData length] > 0) { 
      // Detected new file, enter in all the old data and reset for new data 
      NSError *error; 
      NSDictionary *tempDict = [[NSDictionary alloc] init]; 

      tempDict = [NSPropertyListSerialization propertyListWithData:self.cameraData 
                  options:0 
                   format:NULL 
                   error:&error]; 

      if (error != nil) { 
       // Expected good file but no good file, erase and restart 
       NSLog(@"Error: Failed to convert NSData to NSDict : %@", [error description]); 
       [self.cameraData setLength:0]; 
      } 
... 
      [self.cameraData setLength:0]; 
      [self.cameraData appendBytes:buf length:len]; 

     } else { 
      // Still recieving data 
      [self.cameraData appendBytes:buf length:len]; 
     } 

所以,說我在獲得問題是:

  • 我如何解決我的分析方法給我可靠的結果是不要隨意無法轉換?
  • 或者有沒有比這更好的方法來解析緩衝流爲此目的?
  • 或者我只是在做一些愚蠢或缺少明顯的東西?

回答

1

您似乎是依靠每次寫入流導致相同大小的匹配讀取,你知道這是由NSStream保證?如果沒有,那麼任何讀取都可能包含兩個(或更多)您的編碼字典的一部分,您會看到您看到的解析錯誤。

替代做法:

對於每個編碼的字典來發送:

寫入結束:

  1. 發送包含在編碼的辭典,將遵循的字節大小的消息。
  2. 寫在塊編碼的辭典,最後一個塊可以是短
  3. 重複

讀端:

  1. 閱讀尺寸消息中指定以字節爲單位它的確切長度。
  2. 以塊爲單位讀取編碼字典,確保只讀取(1)報告的字節數。
  3. 重複。

如果您使用的是可靠的通信流,則應該使您可以可靠地讀取每個編碼字典。它避免了你試圖找出每個編碼字典之間的邊界在哪裏,因爲這些信息是協議的一部分。

HTH

+0

令人敬畏的,這個伎倆,採取了很多事件處理這種方式,但現在工作順利。謝謝! – blakemacnair

相關問題