2011-11-22 58 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