2011-01-08 5 views
0

iPhoneでマルチプレイヤーゲームを構築していて、ゲーム内の他のプレイヤーに文字列データを送信する必要があります。そのためには、NSString *文字列データをNSDataオブジェクトにカプセル化する必要があります。 ...ここに私のコードが構成されている方法の例ですiOSの開発:NSDataオブジェクトに文字列をカプセル化するにはどうすればよいですか?

typedef struct 
{ 
    PACKETTYPE packetType; 
    ??? stringToSend; //<---not sure how to store this 
} StringPacket;  

StringPacket msg; 
msg.packetType = STRING_PACKET; 
msg.stringToSend = ... // <---not sure what to do here 
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)]; 

だから私の質問はStringPacketが私のヘッダで定義された構造体である場合、私は簡単にdataWithBytesメソッドを呼び出すことができるように、どのようなタイプstringToSendプロパティがあるべきであり、 NSDataのNSDataオブジェクトにパケットデータをカプセル化するには?

あなたの知恵に感謝します!

答えて

3

まず、NSStringを[NSString UTF8String]を使用してUTF8表現に変換する必要があります。 その後、パケット文字列の長さに格納することをお勧めします。 NSDataのを追加を介して行うことができるすべて、[NSDataのdataWithBytes:]を経由してchar *型から作成されたバックパケットを解析するに

NSMutableData packet = [[NSMutableData alloc] init]; 
[packet appendBytes:&msg.packetType, sizeof(msg.packetType)]; 
char *str = [yourString UTF8String]; 
int len = strlen(str); 
[packet appendBytes:(void*)&len, sizeof(len)]; 
[packet appendBytes:(void*)str, len]; 

、あなたが行う必要があります:私は「以来

NSData packet; // your packet 
[packet getBytes:(void*)&packet.msg range:NSMakeRange(0, sizeof(packet.msg))]; 
int len; 
[packet getBytes:(void*)&len range:NSMakeRange(sizeof(packet.msg), sizeof(len)]; 
NSData *strData = [packet subdataWithRange:NSMakeRange(sizeof(packet.msg) + sizeof(len)), packet.length]; 
NSString *str = [[NSString alloc] initWithData:strData encoding:UTF8Encoding]; 

いくつかのミスがある場合もあります私はあなたがそのアイデアを得るだろうと思っています。

+0

ありがとう、ニコライ!私はあなたが "パケット文字列の長さで格納する"という意味では不明です、文字列の長さを格納する追加のプロパティを作成することを意味ですか?また、私はあなたがNSDataを追加することによって何を意味するのか不明です。あまり仕事がなければ、簡単な例を見せてもらえますか?再度、感謝します! – BeachRunnerFred

+0

わかりやすく読みやすくするために、私の投稿に編集内容を追加しました。 –

+0

ありがとう、ニコレイ、非常にまっすぐ進むようです。もう1つの質問は、データが反対側に到着し、NSDataクラスの 'bytes'メソッドを使用してデータにアクセスするとき、文字列の長さが動的である場合、これらの個々のチャンクにどのようにアクセスできますか? – BeachRunnerFred

2

文字列の長さが最大であれば、それは簡単で効率的です。したがって、これらのパケットの文字列の最大長が255で、文字列をエンコードするためにUTF-8を使用することに決めた場合(どちらのエンコーディングが使用しているエンコーディングに合致する必要があるか)、次のようにします。

typedef struct 
{ 
    PACKETTYPE packetType; 
    uint8_t stringToSend[256]; // UTF8 string with max encoded length of 255 bytes 
} StringPacket;  

StringPacket msg; 
msg.packetType = STRING_PACKET; 
[theString getCString:msg.stringToSend maxLength:256 encoding:NSUTF8StringEncoding]; 
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(StringPacket)]; 

これで、最大255バイトの文字列データとヌルターミネータである適切なC文字列をパケットに入れます。あなたの文字列が与えたサイズでUTF8にエンコードできない場合、メソッドはNOを返すので、実際のコードは実際にそれをチェックしてそれを処理する必要があります。

サイズ制限がない場合は、基本的に同じことができますが、メモリを動的に割り当て、バイトをコピーし、データを作成し、適切なタイミングでメモリを適切に解放し、だからもっと複雑になりますが、基本的な考え方は同じです。 NSStringのメソッド-getBytes:maxLength:usedLength:encoding:options:range:remainingRange:も参照してください。文字列のサイズが動的で完全に不明なこれらのメッセージを生成するのに非常に役立ちます。

しかし、最も単純なケースでは、上記のコードはジョブを完了する必要があります。

+0

ありがとう、ジェイソン! – BeachRunnerFred

+0

これは文字列の長さが異なるため、短い文字列の場合はオーバーヘッドが送信され、長い文字列の場合は文字列が切り捨てられます。 –

+0

@Nickolay:はい、毎回256バイトを送信しますが、すでに述べたように、文字列を切り捨てることはありません。コールが完全に失敗するため、チェックする必要があります。 –

関連する問題