问题
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