无法解码数据 Objective-C
Unable To Decode Data Objective-C
我已连接到向我发送数据的套接字。但我正在尝试将数据转换为字符串,但它不起作用。对话前:
<6d020000 7b225265 73756c74 223a302c 22547970 65223a22 4664732e 49464150 492e4150
49416972 63726166 74496e66 6f222c22 456e6769 6e65436f 756e7422 3a342c22 466c6170
73436f6e 66696775 72617469 6f6e223a 5b7b2246 6c617073 416e676c 65223a30 2c224e61
6d65223a 2230c2b0 222c2253 686f7274 4e616d65 223a2230 c2b0222c 22536c61 7473416e
676c6522 3a307d2c 7b22466c 61707341 6e676c65 223a312c 224e616d 65223a22 31c2b022
2c225368 6f72744e 616d6522 3a2231c2 b0222c22 536c6174 73416e67 6c65223a 317d2c7b
22466c61 7073416e 676c6522 3a352c22 4e616d65 223a2235 c2b0222c 2253686f 72744e61
6d65223a 2235c2b0 222c2253 6c617473 416e676c 65223a35 7d2c7b22 466c6170 73416e67
6c65223a 31302c22 4e616d65 223a2231 30c2b022 2c225368 6f72744e 616d6522 3a223130
c2b0222c 22536c61 7473416e 676c6522 3a31307d 2c7b2246 6c617073 416e676c 65223a32
302c224e 616d6522 3a223230 c2b0222c 2253686f 72744e61 6d65223a 223230c2 b0222c22
536c6174 73416e67 6c65223a 32307d2c 7b22466c 61707341 6e676c65 223a3235 2c224e61
6d65223a 223235c2 b0222c22 53686f72 744e616d 65223a22 3235c2b0 222c2253 6c617473
416e676c 65223a32 357d2c7b 22466c61 7073416e 676c6522 3a33302c 224e616d 65223a22
3330c2b0 222c2253 686f7274 4e616d65 223a2233 30c2b022 2c22536c 61747341 6e676c65
223a3330 7d5d2c22 4675656c 54616e6b 436f756e 74223a32 2c224861 73417574 6f70696c
6f74223a 74727565 2c224e61 6d65223a 22426f65 696e6720 3734372d 34303022 2c225370
6f696c65 72547970 65223a36 7d>
对话后,我得到了这个:"m\^B"。
这是我的代码:
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(@"inputStream is ready.");
uint8_t buf[1024];
NSInteger len = 0;
len = [inputStream read:buf maxLength:1024];
if(len > 0) {
NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
[data appendBytes: (const void *)buf length:len];
NSLog(@"%@", data);
NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self readIn:s];
NSLog(@"%@", s);
}
}
break;
}
前四个字节是 0x0000026D 的小端表示,似乎代表字符串有效负载中的字节数。理论上你可以跳过前四个字节,你会得到你的字符串。
NSData *payload = [data subdataWithRange:NSMakeRange(4, data.length - 4)];
如果你转换它,你会得到:
{
"Result": 0,
"Type": "Fds.IFAPI.APIAircraftInfo",
"EngineCount": 4,
"FlapsConfiguration": [{
"FlapsAngle": 0,
"Name": "0°",
"ShortName": "0°",
"SlatsAngle": 0
}, {
"FlapsAngle": 1,
"Name": "1°",
"ShortName": "1°",
"SlatsAngle": 1
}, {
"FlapsAngle": 5,
"Name": "5°",
"ShortName": "5°",
"SlatsAngle": 5
}, {
"FlapsAngle": 10,
"Name": "10°",
"ShortName": "10°",
"SlatsAngle": 10
}, {
"FlapsAngle": 20,
"Name": "20°",
"ShortName": "20°",
"SlatsAngle": 20
}, {
"FlapsAngle": 25,
"Name": "25°",
"ShortName": "25°",
"SlatsAngle": 25
}, {
"FlapsAngle": 30,
"Name": "30°",
"ShortName": "30°",
"SlatsAngle": 30
}],
"FuelTankCount": 2,
"HasAutopilot": true,
"Name": "Boeing 747-400",
"SpoilerType": 6
}
(我对此进行了美化,但是,这基本上就是 payload
包含的内容。)
请注意,您的代码假定它能够在对 read
的一次调用中读取所有数据。但是你的有效负载比这个例子(621 字节)大,它很容易超过你的缓冲区大小(1024 字节)。或者,如果在您阅读完上一条消息之前收到另一条消息,您可能会遇到麻烦。我建议您实际读取这四个字节以确定预期有多少数据。
要获取字节数,您可以只读取前四个字节,然后将其转换为 uint32_t
:
uint32_t length;
[data getBytes:&length length:4];
length = CFSwapInt32LittleToHost(length); // not technically required on little endian devices, but prudent in case this code is ever run on a big endian environment
然后我会建议从您的流中准确读取该字节数并将其转换为字符串。
我已连接到向我发送数据的套接字。但我正在尝试将数据转换为字符串,但它不起作用。对话前:
<6d020000 7b225265 73756c74 223a302c 22547970 65223a22 4664732e 49464150 492e4150 49416972 63726166 74496e66 6f222c22 456e6769 6e65436f 756e7422 3a342c22 466c6170 73436f6e 66696775 72617469 6f6e223a 5b7b2246 6c617073 416e676c 65223a30 2c224e61 6d65223a 2230c2b0 222c2253 686f7274 4e616d65 223a2230 c2b0222c 22536c61 7473416e 676c6522 3a307d2c 7b22466c 61707341 6e676c65 223a312c 224e616d 65223a22 31c2b022 2c225368 6f72744e 616d6522 3a2231c2 b0222c22 536c6174 73416e67 6c65223a 317d2c7b 22466c61 7073416e 676c6522 3a352c22 4e616d65 223a2235 c2b0222c 2253686f 72744e61 6d65223a 2235c2b0 222c2253 6c617473 416e676c 65223a35 7d2c7b22 466c6170 73416e67 6c65223a 31302c22 4e616d65 223a2231 30c2b022 2c225368 6f72744e 616d6522 3a223130 c2b0222c 22536c61 7473416e 676c6522 3a31307d 2c7b2246 6c617073 416e676c 65223a32 302c224e 616d6522 3a223230 c2b0222c 2253686f 72744e61 6d65223a 223230c2 b0222c22 536c6174 73416e67 6c65223a 32307d2c 7b22466c 61707341 6e676c65 223a3235 2c224e61 6d65223a 223235c2 b0222c22 53686f72 744e616d 65223a22 3235c2b0 222c2253 6c617473 416e676c 65223a32 357d2c7b 22466c61 7073416e 676c6522 3a33302c 224e616d 65223a22 3330c2b0 222c2253 686f7274 4e616d65 223a2233 30c2b022 2c22536c 61747341 6e676c65 223a3330 7d5d2c22 4675656c 54616e6b 436f756e 74223a32 2c224861 73417574 6f70696c 6f74223a 74727565 2c224e61 6d65223a 22426f65 696e6720 3734372d 34303022 2c225370 6f696c65 72547970 65223a36 7d>
对话后,我得到了这个:"m\^B"。
这是我的代码:
case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) {
NSLog(@"inputStream is ready.");
uint8_t buf[1024];
NSInteger len = 0;
len = [inputStream read:buf maxLength:1024];
if(len > 0) {
NSMutableData* data=[[NSMutableData alloc] initWithLength:0];
[data appendBytes: (const void *)buf length:len];
NSLog(@"%@", data);
NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self readIn:s];
NSLog(@"%@", s);
}
}
break;
}
前四个字节是 0x0000026D 的小端表示,似乎代表字符串有效负载中的字节数。理论上你可以跳过前四个字节,你会得到你的字符串。
NSData *payload = [data subdataWithRange:NSMakeRange(4, data.length - 4)];
如果你转换它,你会得到:
{
"Result": 0,
"Type": "Fds.IFAPI.APIAircraftInfo",
"EngineCount": 4,
"FlapsConfiguration": [{
"FlapsAngle": 0,
"Name": "0°",
"ShortName": "0°",
"SlatsAngle": 0
}, {
"FlapsAngle": 1,
"Name": "1°",
"ShortName": "1°",
"SlatsAngle": 1
}, {
"FlapsAngle": 5,
"Name": "5°",
"ShortName": "5°",
"SlatsAngle": 5
}, {
"FlapsAngle": 10,
"Name": "10°",
"ShortName": "10°",
"SlatsAngle": 10
}, {
"FlapsAngle": 20,
"Name": "20°",
"ShortName": "20°",
"SlatsAngle": 20
}, {
"FlapsAngle": 25,
"Name": "25°",
"ShortName": "25°",
"SlatsAngle": 25
}, {
"FlapsAngle": 30,
"Name": "30°",
"ShortName": "30°",
"SlatsAngle": 30
}],
"FuelTankCount": 2,
"HasAutopilot": true,
"Name": "Boeing 747-400",
"SpoilerType": 6
}
(我对此进行了美化,但是,这基本上就是 payload
包含的内容。)
请注意,您的代码假定它能够在对 read
的一次调用中读取所有数据。但是你的有效负载比这个例子(621 字节)大,它很容易超过你的缓冲区大小(1024 字节)。或者,如果在您阅读完上一条消息之前收到另一条消息,您可能会遇到麻烦。我建议您实际读取这四个字节以确定预期有多少数据。
要获取字节数,您可以只读取前四个字节,然后将其转换为 uint32_t
:
uint32_t length;
[data getBytes:&length length:4];
length = CFSwapInt32LittleToHost(length); // not technically required on little endian devices, but prudent in case this code is ever run on a big endian environment
然后我会建议从您的流中准确读取该字节数并将其转换为字符串。