1

我一直在根据 RayWenderlich 的教程开发多人游戏,我的问题是我无法发送任何内容,我尝试NSStringNSData多种编码和解码(UTF8)等方式,但我总是得到类似于\204的东西(颠倒?)B(颠倒?)当我printf在接收端做a时,但是当我做一个NSLog时说(null)。

这是.h的修改部分

typedef struct {
    Message message;
    const char * theTeam;
} MessageGameBegin;

这是让我发疯的.m代码:

 (void)sendGameBegin:(NSString *) team {
    NSString *strSQL = [[NSString alloc]init];
    strSQL = team;
    const char *bar = [strSQL cStringUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"HOOOOOE %@\n",[[NSString alloc] initWithCString:bar encoding:NSUTF8StringEncoding]);

    MessageGameBegin message;
    message.theTeam = bar;
    message.message.messageType = kMessageTypeGameBegin;
    NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageGameBegin)];
    [self sendData:data];

}

然后在接收中,

 ....else if (message->messageType == kMessageTypeGameBegin) {

    MessageGameBegin * beginMessage = (MessageGameBegin *) [data bytes];
    myDecoded = [[NSString alloc] initWithUTF8String:beginMessage->theTeam];
    NSLog(@"NSLOOOOOOOG %@\n",myDecoded);


    printf(" BEGING MESS %s\n",beginMessage->theTeam);
    CCLOG(@"cl BEGING MESS %@\n",myDecoded);

    [self setGameState:kGameStateActive];
    self.enemy = [CCSprite spriteWithFile:myDecoded];

} 

NSLog(@"HOOOOOE %@\n..即使我是 100%,它甚至不会打印到控制台中,它的执行 返回NSLog(@"NSLOOOOOOOG %@\n"..(null) printf给出了奇怪的人类不可读的输出,就像我在 CCSprite 行找不到文件之前显示的那样,因为它说它是 nil

我需要知道我在尝试发送NSSTrings时做错了什么,甚至是更好的方法。请感谢您的帮助,自从我是新手以来,我已经把头发扯掉了 2 天目标c

这是我要开始的教程,它有一个可以在第 2 部分底部下载的源代码 http://www.raywenderlich.com/3276/how-to-make-a-simple-multiplayer-game-with -game-center-tutorial-part-12

编辑: 最重要的是,整个目标是能够发送和接收数据中的字符串......我失败得很惨,所以不胜感激

@borrrden 这是我从你的帮助中得到的

发送:

MessageGameBegin message;
message.theTeam = bar;
message.message.messageType = kMessageTypeGameBegin;
//NSData *data = [NSData dataWithBytes:&message length:sizeof(MessageGameBegin)];
NSMutableData *data = [NSMutableData new];
[data appendBytes:&message length:sizeof(MessageGameBegin)];
[data appendBytes:message.theTeam length:strlen(message.theTeam)];
data.length = sizeof(MessageGameBegin) + strlen(message.theTeam);
[self sendData:data];

接收:

MessageGameBegin msg;
msg.theTeam = [[data subdataWithRange:NSMakeRange(sizeof(msg.message.messageType), data.length-sizeof(msg.message.messageType))] bytes];

NSLog(@"NSLOOOOOOOG %@\n",[[NSString alloc] initWithCString:msg.theTeam encoding:NSUTF8StringEncoding]);

返回看起来更好的东西(颠倒?)ІOarizona.png 好像我的数据长度错误或什么的..我希望它返回 arizona.png ,它总是关闭 3 个字符.. arizona 的 3 前面,所以在这种情况下,是否建议只修剪 3 还是有其他方法?

4

1 回答 1

6

sizeof不是一个神奇的功能。它不会自动知道您的结构在堆中的时间。它只知道它在堆栈上占用了多少字节,不管它有多长Message,加上一个 char 指针的 4 个字节。所以你最终会得到一个指向数据在原始设备上的位置的指针,当在新设备上接收到它时,它只会是垃圾(你很幸运它没有崩溃)。您需要将字符串直接编码到NSData对象中,或者只是采用更简单的方法并创建一个适当的类。如果您要存储指针,我建议创建一个类。然后你可以实现NSCoding轻松转换NSData

编辑:

如果你真的必须自己做结构,你将不得不手动把NSData. 我仍然建议简单地上课。

假设我有这个结构:

typedef struct
{
    int testInt;
    const char *testString;
} SO2Test;

我可以这样编码:

SO2Test test;
test.testInt = 5;
test.testString = "TEST";
NSMutableData *data = [NSMutableData new];
[data appendBytes:&(test.testInt) length:sizeof(int)];
[data appendBytes:test.testString length:strlen(test.testString)];
data.length = sizeof(int) + strlen(test.testString);

这对字符串做出了一些严格的假设,例如字节顺序(如果您在两个 iOS 设备之间发送,这无关紧要,因为它们都是相同的)并且字符串是每个字符 1 个字节。如果您的字符串由于某种原因是 UTF-16,这将失败,因为它可能会提前达到 NULL 终止字符。你现在明白为什么上课会让你的生活更轻松了吗? NSString将为您处理所有这些废话。

如果没问题,那么您可以像这样在另一边继续:

SO2Test test2;
int *intPtr = (int *)[[data subdataWithRange:NSMakeRange(0, sizeof(int))] bytes];
test2.testInt = *intPtr;
test2.testString = [[data subdataWithRange:NSMakeRange(sizeof(int), data.length-sizeof(int))] bytes];
于 2013-02-04T04:36:41.110 回答