GCDAsyncSocket改变数据,同时其输送(GCDAsyncSocket alters dat

2019-09-20 20:41发布

我在做一个多人的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,0×69(0x73)的,0x74,的0x30,的0x30)”

我看着发送和接收的数据的描述,发现数据来改变所述接收装置1)和2)截断。

当我过的GameKit协议,游戏中心和蓝牙发送完全相同的数据有这样没问题 - 我收到的数据不变,那么显然问题出内心深处的某个地方GCDAsyncSocket。

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

Answer 1:

It is because of this: The TCP protocol is modeled on the concept of a single continuous stream of unlimited length. You need to either appending to your data some type of terminator indicator and using the readDataToData method. Or you need to prefix your data with an indicator for the length of your data. So when you use readDataWithTimeout, you can extract the exact number of bytes out of the incoming TCP stream.

An example of how to use the terminator from the author of the 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.



文章来源: GCDAsyncSocket alters data while transporting it