GCDAsyncSocket alters data while transporting it

限于喜欢 提交于 2019-12-23 04:01:54

问题


I'm making a multiplayer iOS game and have run into the following issue: i send a dictionary with an array of custom objects inside it. These custom objects conform to NSCoding. I convert the dictionary to NSData like this:

 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:packet];

Then send it

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

Receive

[sock readDataWithTimeout:-1 tag:tag];

And try to unarchive

NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Everything looks extremely simple, but the app crashes while unarchiving the data and i receive the following error

[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30)'

I looked at the description of the data sent and received and found that the data comes to the receiver device 1)altered and 2)truncated.

When i send exactly the same data over GameKit protocols, Game Center and bluetooth there's no problem like this - i receive the data unchanged, so obviously problem lies inside somewhere deep in GCDAsyncSocket.

Did anyone ever encounter such a trouble? Thanks


回答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.



来源:https://stackoverflow.com/questions/11826195/gcdasyncsocket-alters-data-while-transporting-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!