2011-11-22 59 views
0

我正在學習使用cocoaAsyncSocket爲我的TCP連接開發iPad應用程序。Objective C NSData到NSString

當我將NSData打印到控制檯時,它以十六進制打印整個數據。當我轉換爲NSString並打印時,它總是隻打印第一個字節。

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { 

NSString *msg = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];

NSLog(@"Server Reply data: %@", data);

NSLog(@"Server Reply: %@",msg); }

從控制檯打印出來是: 「服務器返回數據:< 4b000230 30303037 33323030 35342020>」 「服務器回覆:K 「

我轉換錯了嗎?

當數據讀取十六進制ETX(03)爲cocoaAsyncsocket可以停止嗎?我看到可以閱讀CRLF。

謝謝。

回答

1

嘗試

NSString *aString = [[NSString alloc] initWithData:aNSData encoding:NSUTF8StringEncoding]; 
+0

cocoaasyncsocket有這個分隔符來結束msg的權利嗎?缺省值是CRLF'返回[NSData的dataWithBytes: 「\ X0D \ 0A」 長度:2];' 使用您的方法進行解碼,它僅適用於'返回[NSData的dataWithBytes: 「」 長度:1];' 因爲repy以ETX結束,所以我將它改爲'return [NSData dataWithBytes:「\ x03 \」length:1];' 它只返回第一個字符串字符,當我用你的方法把數據改成字符串時.. – kraitz

2

4b000230 30303037 33323030 35342020,解析爲UTF8是兼容ASCII碼0x4b(或 'K'),然後一個0×00,這被解釋爲終止NULL。所以NSString的行爲完全正確。

是否有可能你正在接收UTF16或其他編碼?

編輯︰如果它只是你得到兩個字節不是字符串的一部分(基於評論中的示例它看起來像整個數據包的長度,包括兩個字節包含那麼你可以這樣做:

NSData *originalData = <whatever came back from the web service>; 
NSData *subData = [NSData 
        dataWithBytes:((char *)[originalData bytes]) + 2 
          length:[originalData length] - 2]; 

這將導致數據被複制。如果你真的想要,但可以避免這種情況,但是語義會變得更加混亂,並且不會在後臺對Web服務產生顯着影響。第3個字節

手動解碼以後,這個看起來像流是:

02 [start of text control code; NSString will render this as ¿] 
30 0 
30 0 
30 0 
30 0 
37 7 
33 3 
32 2 
30 0 
30 0 
35 5 
34 4 
20 [space] 
20 [space] 

這是否看起來像那種你希望找到的東西?既然0x02或0x03都不會導致NSString終止,如果你對長度有信心,那麼我認爲最簡單的做法就是在NSString創建後刪除它們(通過stringByReplacingOccurrencesOfString或NSMutableString的replaceOccurrencesOfString:withString:options:range:,從而避免任何錯誤其中0x02或0x03作爲多字節字符的一部分在字節流中突然出現。

+0

我不認爲我收到的是其他編碼。是否有可能轉換終止於NULL? – kraitz

+0

轉換確實在NULL處終止,但這是因爲NULL終止了C字符串。 Unicode似乎將其定義爲控制字符。如果你得到一個HTTP響應,頭部是否有編碼?無論如何,你知道你期望收到什麼字符串嗎? – Tommy

+0

味精以STX(02)開頭,以ETX(03)結束。 當cocoaasyncsocket讀取數據時,它有一個分隔符,當我將分隔符設置爲「」時,它讀取並轉換整個數據,當我將它設置爲ETX(「03」)時,它只轉換第一個字符。 – kraitz