GCDAsyncSocket在传输数据时会改变数据

我正在制作一款多人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深处。

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

正因为如此: TCP协议是基于无限长度的单个连续流的概念建模的。 您需要向data附加某种类型的终结符指示符并使用readDataToData方法。 或者,您需要在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]; 

之所以你不必使用GameKit完成上面提到的所有操作,是因为GameKit协议会为你完成所有这些。