1

RayWenderlichのチュートリアルに基づいてマルチプレイヤーゲームを開発してきましたが、問題は送信できないことNSStringですNSData。エンコードとデコード(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行がファイルを見つけることができない前に示したように、人間が読めない奇妙な出力を提供します。

NSSTringsを送信するこの試みで、何が間違っているのか、またはそれを行うためのより良い方法を知る必要があります。 Objective 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文字ずれています..アリゾナの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);

ただし、エンディアン (2 つの iOS デバイス間で送信する場合はどちらも同じであるため問題ありません) や、文字列が 1 文字あたり 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 に答える