0

私は本質的にSOAPのようにXMLを前後に交換する小さなアプリを書いています。OS X ベースのサーバーと iPad クライアントがあります。クライアントで使用KissXMLし、サーバーで組み込みの XML パーサーを使用します。私はGCDAsyncSocket通信するために両方を使用します。

iPad シミュレーターでアプリをテストすると、完全な XML が表示されます。すべて正常に動作します。

ただし、開発デバイス (実際の物理 iPad) を使用すると、他のすべては正常に動作しますが、XML は 1426 文字目以降で終了します。このエラーは、複数の iPad で発生することを確認しています。

着信パケットをサブスクライブすると、以前は単純なものGCDAsyncSocketを使用 していましたが、どちらも同じ結果になりました。シミュレーターでの実行は問題ないため、GCDAsyncSocket のせいではないようです。atは「無限」バッファを示すことに注意してください。[sock readDataWithTimeout:-1 buffer:[NSMutableData new] bufferOffset:0 maxLength:0 tag:0];[sock readDataWithTimeout:-1 tag:0];0maxLength

誰がこれを引き起こしているのか考えていますか?

4

3 に答える 3

2

1426 は、送信できる最大 TCP データのサイズである MTU (Maximum Transmit Unit) によく似ています。ネットワーク メディアや構成によってサイズは異なりますが、1426 はかなり一般的です。

これは、TCP パケットの受信と XML メッセージの完了を混同していることを示唆しています。TCP パケットが XML メッセージ境界で終了するという保証はありません。GCDAsyncSocket は、XML ではなく TCP を扱う低レベルのライブラリです。

各パケットを取得したら、それを に連結し、NSMutableDataいつ処理するのに十分なのかを判断するのはあなたの責任です。プロトコルがすべてのメッセージの後に接続を閉じる場合、接続が閉じられるまで読み取ることができます。そうでない場合は、特定のパケットに次のメッセージの一部が含まれている可能性があるという事実に対処する必要があります。境界がどこにあるかを判断するには、データを十分に解析する必要があります。

ところで、お使いの Mac が iPad とは異なる MTU を持っている可能性が非常に高いため、異なるプラットフォームで異なる動作が見られる可能性があります。

于 2012-03-13T02:51:12.877 に答える
1

解決策は、指定されていない場合AsyncSocket、次の改行を探すことでした。パケットが終了すると、実際に回線が返されます。私が使用していた (sockは私の GCDAsyncSocket オブジェクトです)

[sock readDatawithTimeout:-1 tag:0]

しかし、その後に移動しました

[sock readDataToData:[msgTerm dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0]

ここで、msgTermは "\r\n\r\n" として定義された外部定数 NSString であり、クライアントとサーバー ソースの間で共有されます。これにより、パケットを終了させるライン リターンの問題が効果的に回避されます。

このソリューションに関する追加の注意: SOAP のようなプロトコルを使用しているため、空白は問題になりません。ただし、空白行を終了することに気難しい場合は[incomingDecodedNsstringMessage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]、クリーンアップのような方法を使用できます。

于 2012-03-15T03:50:03.263 に答える
0

のコードを見てみるGCDAsyncSocketと、バグがある可能性は十分にあると思います。たとえば、安全なソケットを読み取っている場合、iPhone では通常の Unix スタイルのファイル記述子の代わりに cfsocket メカニズムが使用され、作成者はソケットがいつ閉じられるかについて無効な仮定をしている可能性があります。ソースコードがあるので、デバッガーでステップスルーして、ファイルの終わりに時期尚早にフラグが立てられていないかどうかを確認します。

TCP はストリームベースのプロトコルです。理論的には、基盤となる IP プロトコルのパケット サイズに違いはありませんが、ソケットを十分に高速に読み取ると、特に IP スタックが何らかの方法でメモリの使用に合わせて調整されている場合は、IP パケットのサイズのチャンクでデータを取得できる可能性があります (ここで推測!)。

于 2012-03-13T10:31:42.100 に答える