Ios 无法解码数据Objective-C

Ios 无法解码数据Objective-C,ios,objective-c,sockets,decoding,Ios,Objective C,Sockets,Decoding,我连接到一个向我发送数据的套接字。但我试图将数据转换为字符串,但它不起作用。对话前: <6d020000 7b225265 73756c74 223a302c 22547970 65223a22 4664732e 49464150 492e4150 49416972 63726166 74496e66 6f222c22 456e6769 6e65436f 756e7422 3a342c22 466c6170 73436f6e 66696775 72617469 6f6e223a 5b7

我连接到一个向我发送数据的套接字。但我试图将数据转换为字符串,但它不起作用。对话前:

<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>
前四个字节是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
}
(我对此进行了美化,但这基本上就是
负载所包含的内容。)


请注意,您的代码假定它能够在一次调用
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

然后,我建议您从流中准确地读取该字节数,并将其转换为字符串。

前四个字节是0x0000026D的一个小的endian表示,似乎表示字符串负载中的字节数。从理论上讲,您可以跳过前四个字节,然后得到字符串

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
}
(我对此进行了美化,但这基本上就是
负载所包含的内容。)


请注意,您的代码假定它能够在一次调用
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
然后我建议从您的流中准确地读取该数量的字节,并将其转换为字符串