2009-07-31 13 views
5

Game Kitフレームワークを使用して、アプリケーションを実行している他のiPhoneとデータをやりとりするアプリケーションを作成しようとしています。 iPhoneはお互いを見つけて接続しても問題はありませんが、データを送信すると問題が発生します。私はiPhoneが正しく接続されていることを知っている。なぜなら私がNSStringをシリアル化して接続を介して送ると、それはもう一方の端でうまくいくからだ。しかし、NSKeyedArchiverを使って大きなオブジェクトをアーカイブしようとすると、エラーメッセージ "AGPSessionBroadcast failed(801c0001)"が表示されます。iPhone:Game Kitで大量のデータを送信する

私が送信しているデータが大きすぎると仮定しています(私のファイルのサイズは約500kです。Appleは最大95kを推奨しているようです)。私はいくつかの転送にデータを分割しようとしましたが、私はそれを他端で適切に解凍することはできません。他の誰かがこの問題を抱えているのか、それをどのように解決したのか、私は疑問に思います。

答えて

4

私は300K前後のファイルで同じ問題がありました。問題は、送信者が次のチャンクを送信する前に受信者がパイプを空にしたことを知る必要があることです。

私はシンプルな状態エンジンの両側に走ってしまった。送信者は、送信される総バイト数とパケットサイズをヘッダに送信し、パケットサイズを確認して、相手方からの確認応答を待ちます。ハンドシェイクを取得すると、シーケンス番号でスタンプされた固定サイズのパケットが送信されます。

受信者はそれぞれを取得し、読み取ってバッファに追加し、シーケンス#でパケットを受け取ったことをパイプに書き戻します。送信者はパケット#を読み取り、別のバッファの値をスライスし、以下同様に続きます。各サイドは、アイドル状態、ヘッダーの送信、データの送信、データの受信、エラー、完了など)を把握しています。最後の部分を読み書きするタイミングを把握しておく必要がありますバッファ全体のサイズよりも小さくなる可能性があります。

これはうまく動作しますが(少し遅くなります)、任意のサイズに拡大縮小できます。私は5Kのパケットサイズで始めましたが、かなり遅くなりました。それを10Kにプッシュしましたが、問題が発生し始めたので、8096に戻して保持しました。バイナリデータとテキストデータの両方でうまく動作します。

+0

こんにちはラミン、提案したソリューションに関連するコードスニペットを共有できますか。 – Anshul

3

GameKitは一般的なファイル転送APIではありません。現在の場所やその他のオブジェクトが何であるかなど、プレイヤーがどこにあるかを更新するためのものです。一般的な共有メカニズムのためにAPIをハイジャックすることは理解できますが、ゲーム用に300kを送信することは賢明ではありません。

問題は、TCP接続ではないことです。より多くのUDP(データグラム)接続です。このような場合、データはストリーム(TCPによってパケット化される)ではなく、むしろ巨大なデータである。 (技術的には、UDPは複数のIPパケットに断片化することができますが、それらのうちの1つを失い、UDP全体が失われます。

ほとんどの有線ネットワークのMTUは〜1.5kです。ブルートゥースの場合、約0.5kです。したがって、あなたが送った(a)UDPパケットは失われるかもしれませんし、(b)複数のMTUサイズのIPパケットに分割されるかもしれませんし、(c)それらのパケットのひとつが失われた場合、あなたは自動的にセット全体を失います。

あなたの最良の戦略は、TCPをエミュレートすることです。シーケンス番号を持つパケットを送信します。その後、受信側は、後で欠落したパケットの詐欺送信を要求することができる。 NSKeyedArchiverに相当するものを使用している場合は、キーを反復して個々のキーとして書き出すことをお勧めします(各キー値はそれほど大きくないと仮定して)。送り返されるパケットごとにある種のACKと、完了したときの合計ACKが必要なので、送信者はメモリからデータを削除することができます。

関連する問題