我有一个Python服务器,使用struct.pack函数将数据作为字节发送到客户端。数据构造为struct.pack("!bhhh", 0x1, x, y, z)
。
如何在Objecive-C中回读客户端的所有参数?
我现在使用以下代码:
NSString *command = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
得到一个结果
ÿÿÿø
答案 0 :(得分:0)
这不是字符串数据。不要使用NSString。
您需要定义具有等效布局的结构。这有点棘手,因为您使用的结构奇怪地对齐:
struct __attribute__((__packed__)) {
uint8_t b;
uint16_t h1, h2, h3;
} *bhhh = (void *) buffer;
您现在可以将该字段的内容称为bhhh->b
,bhhh->h1
等。
请注意,我使用的名称都是完全虚假的,因为我不知道数据代表什么。不要逐字复制。
答案 1 :(得分:0)
由于您使用的是!
前缀,因此数据是以Big Endian编写的。这可以防止您简单地将输入数据类型转换为适当的类型。
因此,您需要使用按位移位计算单词(您的三个h
值)。您可以轻松创建宏来简化此操作:
// Read a byte (b) from buf at pos
#define GET_B(buf, pos) (uint8)buf[0]
// Read a (signed) word (H) from buf at pos
#define GET_h(buf, pos) ((int8_t)buf[pos+1] | (int8_t)buf[pos]<<8)
// Read an (unsigned) word (h) from buf at pos
#define GET_H(buf, pos) ((uint8)buf[pos+1] | (uint8)buf[pos]<<8)
使用此示例输入如下所示:
// created with struct.pack('!bhhh', 1, -200, -300, -400)
unsigned char input[] = {0x01, 0xff, '8', 0xfe, 0xd4, 0xfe, 'p'};
NSLog(@"a: %d", GET_B(input, 0));
NSLog(@"x: %d", GET_h(input, 1));
NSLog(@"y: %d", GET_h(input, 3));
NSLog(@"z: %d", GET_h(input, 5));
请注意不同数据类型占用的字节数。 b
只是一个字节,但h
是两个字节。因此,偏移量为0,1,3和5.