1

我正在制作多人 iOS 游戏并遇到以下问题:我发送了一个字典,其中包含一组自定义对象。这些自定义对象符合NSCoding. 我将字典转换成NSData这样:

 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:packet];

然后发送

[asyncSocket writeData:data withTimeout:-1 tag:tag];

收到

[sock readDataWithTimeout:-1 tag:tag];

并尝试取消归档

NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];

一切看起来都非常简单,但应用程序在取消归档数据时崩溃,我收到以下错误

[NSKeyedUnarchiver initForReadingWithData:]:无法理解的存档(0x62、0x70、0x6c、0x69、0x73、0x74、0x30、0x30)'

我查看了发送和接收数据的描述,发现数据到达接收设备 1) 更改和 2) 截断。

当我通过 GameKit 协议、Game Center 和蓝牙发送完全相同的数据时,就没有这样的问题——我收到的数据没有改变,所以很明显问题出在 GCDAsyncSocket 深处的某个地方。

有没有人遇到过这样的麻烦?谢谢

4

1 回答 1

3

正因为如此:TCP 协议以无限长度的单个连续流的概念为模型。 您需要附加到data某种类型的终结符指示符并使用 readDataToData 方法。或者,您需要在您data的前缀前面加上data. 因此,当您使用 readDataWithTimeout 时,您可以从传入的 TCP 流中提取确切的字节数。

GCDAsynsSocket的作者提供的如何使用终止符的示例:

NSString *welcomeMsg = @"Welcome to the AsyncSocket Echo Server\r\n";
    NSData *welcomeData = [welcomeMsg dataUsingEncoding:NSUTF8StringEncoding];

    [newSocket writeData:welcomeData withTimeout:-1 tag:WELCOME_MSG];

    [newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:0];

The reason why you do not have to do all the mentioned above with GameKit because GameKit protocols take care all of that for you.

于 2012-08-06T10:44:52.490 回答