0

私は、Python Twisted バックエンドとやり取りする iPhone アプリケーション用のネットワーク コードに取り組んでいます。最近、私の NSOutputStream が送信時にペイロードを 2 倍にしている、またはツイストが受信時にペイロードを 2 倍にしているような問題に遭遇しました。

「アップル推奨」スタイルの TCP ソケット、EG 非ポーリングを使用しています。

プロセスは次のとおりです。
CLIENT
    - NSStreamEventHasSpaceAvailable: X バイトのデータのパケットを送信します
    - NSStreamEventHasSpaceAvailable: Y バイトのデータの別のパケットを送信します
SERVER
    - Twisted はサイズ (X + Y) バイトのパケットを受信します

outputStream のステータスが「NSStreamStatusWriting」の場合、明示的にデータを送信しないようにしています。また、NSStreamEventHasSpaceAvailable がスローされていない場合、クライアントからのデータの送信が許可されないようにします。

このペイロードの二重化/合併の原因について何か考えはありますか? Twisted のコードはかなり単純で、プロトコルで標準の dataReceived を使用しています。

    def dataReceived(自己、データ):
        # データの処理方法を決定するためにロジックを実行する
        # ...
        # ここに len(data) を出力すると、マージされたパケット サイズが明らかになります

iOS コードもかなり標準的です。

    if (eventCode == NSStreamEventHasSpaceAvailable)
    {
        [outputStream 書き込み:[パケット getData] maxLength:[パケット getPacketSize]];
    }
    // [packet getData] は単に標準の UInt8 配列を返します。
    // [packet getPacketSize] はその配列のサイズを返します。

上記の iOS コードが連続して 2 回呼び出されると (たとえば、2 つのパケットを次々に送信する)、ツイスト コードはマージされたデータ サイズを報告します。

アドバイスや提案をお寄せいただきありがとうございます。

4

1 に答える 1

1

私は同意します -- バッファの境界が一致するとは必ずしも期待すべきではありませんが、それは予測可能な動作の問題だと思います。

TCP ベースの通信では予測可能な動作はありません。ルーター、NAT 境界、間抜けなプロキシなど、ユーザーとリモート ホストの間に、予期しない動作を指示するものがいくつも存在する可能性があります。

一体、あなたのパケットをバイト単位で運ぶ伝書鳩さえいるかもしれません。

ただし、実際の動作は一般的にかなり予測可能です。しかし、常にではなく、常に 100% というわけではなく、どこかでチューブが詰まっている顧客の可能性が常にあります。

TCP を使用すると、少なくとも、エラーが発生しない限り、通常、パケットは送信された順序で受信されることが保証されます。繰り返しますが、その間のすべてのポイントが正しく実装されているか、悪意がないと仮定します (後者のビットは、データが破損する場合があると想定する必要があることを意味します)。

その保証でさえ、あまり意味がありません。10 個のパケットのうち最初の 8 個を受信する可能性があります... または、すべての受信データを受信して​​、応答しようとしたときに送信接続が切断されていることを確認するだけである可能性があります....

要点; 両側のバッファリング アルゴリズムは、バッファがランダム バーストで満たされる可能性があることを想定する必要があります。これは、そもそも反対側にスタックしているデータのサイズと完全に一致しません。厳密に必須というわけではありませんが、アプリはランダムな接続障害から防御することで最適に機能します。切り捨てられたバッファ、ランダムに切断された接続、およびデータの破損に対して。

初期のバイト長フィールドとチェックサムはあなたの味方です。仮定はあなたです !hjfdahjdas8y! $(& ($@#&^@#)^&! @#& _[接続が失われました]

于 2011-05-10T04:45:56.290 に答える