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协议会为你完成所有这些。