2013-07-03 55 views
0

我正在開發一個需要將客戶端(iPhone)連接到服務器的項目。我已經使用CFStream,NSStream等完成了這項工作。服務器發送需要在客戶端「逐個」處理的數據包。問題在於有時服務器一個接一個地發送兩個數據包,所以我在客戶端接收到的數據包(通過[inputStream hasBytesAvailable])是兩個數據包的串聯。處理來自服務器的數據

從服務器到客戶端的數據包的體系結構是「數據」+ b'00000000'(二進制NULL)。我想知道如何讓程序知道當有'00000000'字節時,它必須處理該數據包並清空緩衝區。

這裏是我使用的代碼:

case NSStreamEventHasBytesAvailable: 

    if (theStream == inputStream) { 

     uint8_t buffer[1024]; 
     int len; 

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

       NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; 

       if (nil != output) { 
        [self processData:output]; 
        NSLog(@"OUTPUT: %@", output); 
       } 
      } 
     } 
    } 
    break; 

一個例子。服務器發送: msg1_whatever(串聯起來)b'0000000' 及後inmediatly的是,它發送: msg2_whatever + b'00000000'

然後,將的NSLog顯示: msg1_whatever + b'00000000'msg2_whatever + B '00000000'

而不是兩個分離的字符串。如果在發送msg1和msg2之間有一段時間,那麼它可以很好地工作,但是這個異常需要處理,因爲它會發生多次。

回答

1

您需要重新設計您的協議。這裏的主要問題是,你沒有給出你在消息本身之前發送的消息的大小,因此你不知道從每個消息的輸入流中讀取多少。

下面是一個非常簡單的協議的例子。每條消息由兩個字段組成:

  1. 大小(無符號整數)。
  2. 消息本身。

然後,對於每條消息,您讀取兩次。首先,您閱讀郵件大小sizeof(unsigned int),然後閱讀郵件本身(您現在知道它的大小)。

這也消除了消息之間空分隔符的必要性,如果不正確地轉義消息,這些消息可能發生在消息內部,並且可能導致嚴重問題。