1

バックグラウンド:

私がプログラミングしているアプリケーションは、非同期ソケット (BeginSend、EndSend、BeginReceive、EndReceive を使用) を使用して相互にデータを送信します。ソケットは TCP であり、IPV4 ではソケット フラグはありません。

これは、4 バイト (int) のメッセージを送信するシステムを使用し、その後に前のメッセージで指定された長さのメッセージが続きます。MessageLength と MessageBody を処理する関数ヘルパーを使用します。流れはこんな感じ

  1. BeginReceive()
  2. EndReceive()
  3. MessageLengthReceived()
  4. BeginReceive()
  5. MessageBodyReceived()

問題:

ファイルデータを16kbのチャンクで送信すると、問題が発生します(オフセット、pieceIndexなどの小さなオーバーヘッドが追加されます)。MessageLength を受信するときに、実際のメッセージの長さではなく、前のメッセージのランダムな部分からデータを受信することがあります。この問題の一部は、設定されたオフセット (ファイルの先頭または末尾 / ピース / 16 kb のチャンクなど) で常に発生するとは限らず、どのファイルでも発生する可能性がありますが、より多くのファイルや大きなファイルを送信するとさらに発生する可能性があります。 .

この問題が発生しない内部メッセージ (RequestMessages など) が送信されます。すべての内部メッセージは 100 バイト未満です。

別のチャンクを要求する前に、ファイル チャンクが完全に保存されるのを待ってみましたが、それでも失敗します。また、一度に送信するチャンクの数を制限しようとしましたが、これは 127.0.0.1 (ローカル クライアント) を使用する場合にのみ問題を解決し、クロス ネットワーク (LAN) では解決しません。

アプリケーションに問題がないかどうかを確認するために何時間も費やしましたが、間違ったデータをヘッダーとして送信する場所はまだ確認していません。この問題は常に、2 つのクライアントの送信と受信の間にあるようです。使用すべきソケット/送信方法の設定はありますか? または、ある種の競合状態である可能性があります (競合状態について考えましたが、データがファイル内のどこにでもランダムに存在する可能性があるという事実により、これを再考しました)。

4

1 に答える 1

0

質問から、あなたが扱っている問題は MonoTorrent ライブラリ内にあると思います。

私自身、そのような問題に遭遇したことはありません。コードを見ると、ネットワークIOは最初のメッセージが処理されるまで2番目のメッセージを受信しようとしないため、受信部分はすでに注文されていると思います。PieceMessages の書き込み要求も DiskIO でキューに入れられるため、問題になることはありません。

ただし、送信手順では、複数の場所から ProcessQueue 関数を呼び出すことができます。また、ProcessQueue によって間接的に呼び出された EnqueueSendMessage は、実際にはメッセージをどのキューにもエンキューしません。Socket.BeginSend を呼び出すだけです。Socket.BeginSend() にキューメカニズムが含まれているかどうかはわかりません。存在しない場合、複数のスレッドが同じソケット「BeginSend」を別のデータにしようとしたときに問題が発生する可能性があります。

于 2012-05-03T10:04:52.170 に答える