1

タイトルで私の問題を説明する方法がよくわかりませんでしたが、私の問題について詳しく説明します。

基本的に、私は P2P ではなく、すべてのユーザーが IRC と同様に中央サーバーに接続するチャットをコーディングしています。接続は非同期で、ほとんど問題なく動作します。主な問題は、大量のデータが 1 人のユーザー (または 1 人のユーザーからサーバー) に一度に送信されると、バイトがマージされてエラーが発生する可能性があることです。残りのデータの前にデータの長さを含む 4 バイトのヘッダーを追加することで、これに取り組みました。それでも、バイトはマージされているようです。また、 NoDelaytrueに設定し、DontFragmentfalseに設定しようとしました。それでも、うまくいきません。

問題は、バイトがマージされるときに、最初のバイトのみを処理し、残りのバイトは何もしないことだと思います。この問題にアプローチする最善の方法は何でしょうか?

コールバック コードを受け取る: http://pastebin.com/f0MvjHag

4

2 に答える 2

3

それが彼らがそれをストリームと呼ぶ理由です。バイトを一方の端に入れると、TCP はそれらが同じ順序で出てくることを保証し、欠落したり重複したりせずに遠端に出ます。バイトより大きいものはすべて問題です。

ヘッダーを取得するには、バッファーに十分なバイトを蓄積する必要があります。次に、それを解釈し、追加のバイトの処理を開始します。次のヘッダーを開始するためにいくつか残っている場合があります。

これは正常な動作です。アプリケーションがデータを受信して​​いない場合、システムはデータをバッファリングします。次回リクエストを行ったときに、利用可能なデータを引き渡そうとします。一方、大きな書き込みは、適切なフレーム サイズをサポートしていない接続を経由する場合があります。それらは必要に応じて分割され、最終的にはドリブとドラブで到着します。

于 2012-08-03T22:52:23.697 に答える
2

これは通常、データの 2 つ以上のパケットが短い間隔で送信される場合に発生します。私は最近この問題を自分で抱えていましたが、それを解決する方法は分離キーでした。その後、各メッセージをトークン化できます。たとえば、私が行ったように、送信される各メッセージの末尾に ASCII 文字 #4 (送信終了文字) を追加できます。

Write("Message1" + ((char)4).ToString())
Write("Message2" + ((char)4).ToString())

次に、クライアントがデータを受信すると、受信したデータを反復処理できます。その特殊文字を見つけると、それが 1 つのメッセージの終わりであり、(おそらく) 新しいメッセージの始まりであることがわかります。

"Message1(EOT char)Message2(EOT char)"

\nASCII 文字を使用するよりも扱いやすい場合があります。

于 2012-08-03T22:56:29.980 に答える