2016-06-16 52 views
1

在我的應用程序中,我使用NSStreams進行客戶端服務器通信。在事件hasbytesAvailabledelegate方法,當我讀數據的返回nullNSinputstream讀取數據返回空值?

案例:當長度爲4096,然後讀取失敗並返回零;意思是當長度等於緩衝區大小時,它不能讀取,即使我把maxlength設置爲4000,緩衝區大小設置爲4096,那麼每當4000字節被讀取失敗時也是如此。該怎麼辦?

下面是代碼:

case NSStreamEventHasBytesAvailable: 

    if (aStream == inputStream) { 
      uint8_t buffer[4096]; 
      int len; 
      while ([inputStream hasBytesAvailable]) {      
       len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 
       NSLog(@"\nThe length is -- %d\n",len); 
        if (len > 0) { 
          NSData *data = [[NSData alloc] initWithBytes:buffer length:len]; 
          output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
           // output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];        
           } 
        } 
       }   

     NSLog(@"\n\n%@\n\n",output); 
+0

我沒有看到任何錯誤報告,所以這是任何人的猜測。 – Droppy

+0

我不知道,但可以把它與此有關:http://stackoverflow.com/questions/36894972/why-doesnt-cast-work-from-nsdata-to-string-swift/?我的意思是,當緩衝區已滿(長度爲緩衝區大小),這意味着有一個很大的機會,這只是數據的一部分嗎? – Larme

+0

@Droppy,沒有錯誤來了,但它是在的情況下 –

回答

0

我認爲的代碼是絕對沒問題,它應該讀出的數據,可能是你讀過4096個字節後,可能會有一些更多的字節可用,繼續循環,並且再次初始化輸出變量,所以你可能錯過它。

使用下面的代碼片段:

if (aStream == inputStream) { 
        uint8_t buffer[4096]; 
        int len; 
        NSString* tempOutput = @""; 

        while ([inputStream hasBytesAvailable]) { 

         len = (int)[inputStream read:buffer maxLength:sizeof(buffer)]; 
         NSLog(@"\nThe length is -- %d\n",len); 
         if (len > 0) { 
          NSData *data = [[NSData alloc] initWithBytes:buffer length:len]; 
          output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
          tempOutput = [tempOutput stringByAppendingString:output]; 
           // output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 

           } 
        } 
       output = tempOutput; 
       } 
+0

這是一個非常天真的方法。 – Droppy

+0

可能,但也可能達到目的 –

+0

我的'output'至少追加到'tempOutput'如果'output'不爲零,如果它是零,追加數據。 – Larme

1

數據從網絡連接將不總是在它被髮送在相同大小的塊被接收的讀這意味着接收器需要:

  1. 確切地知道消息中需要多少數據。
  2. 請記住當前消息中的任何「遺留」數據,因爲它屬於下一條消息。

正確執行此操作最簡單的方法之一是以字節計數對消息加前綴,然後只嘗試從網絡連接讀取大量數據。這將剩下的數據留在「網絡緩衝區」中,直到客戶端需要它爲止。

您的代碼正在接收一個字符串,這將是NUL終止,所以這意味着您需要讀取固定大小的塊中的數據,檢查每個字節,直到找到字符串尾部,然後粘合在將其轉換爲字符串之前將其分塊。然後您需要記住下一條消息的任何「遺留」數據。複雜的東西,呃?

我會去消息大小前綴,因爲這是幾乎所有人都做的。