3

TCP、DCCP、および UDP プロトコルを切り替えることができる単純なサーバーおよびクライアント アプリを作成しました。目標は、あるファイルから別のファイルに転送し、各プロトコルのトラフィックを測定することでした。これにより、さまざまなネットワーク設定でそれらを比較できます (結果がどうなるかは大まかにわかっていますが、正確な数値/グラフが必要です)。とにかく、異なるコンピューターで両方のアプリを起動して tcpdump を起動した後、4GB ファイルから最初の数 MB (~50MB) しか tcpdump ログに記録されません。アプリは標準の C/C++ コードで記述されており、Web 上のどこにでもあります。ここで何が問題なのか、何が間違っているのでしょうか?

--編集

私が使用するコマンドラインは次のとおりです。

tcpdump -s 1500 -w mylog

tcpdumpは、最初の ~55 秒だけパケットをキャプチャします。それは、クライアントがファイルをソケットに送信する必要がある時間です。その後、サーバーはファイルの受信とハード ドライブへの書き込みを続けますが、停止します。

--編集 2

ソースコード:

client.cpp
server.cpp
common.hpp
common.cpp

--最終編集

多くの人が指摘したように (そして私が疑ったように)、ソース コードにはいくつかの誤解/バグがありました。クリーンアップした後 (またはほとんど書き直した後)、必要に応じて tcpdump で動作します。@Laurent Parenteau からの回答を受け入れますが、問題に関連するのはポイント 5のみです。誰かが正しいコードに興味があるなら、ここにあります:

ソースコード編集

client.cpp
server.cpp
common.hpp
common.cpp

4

5 に答える 5

7

コードには多くの間違いがあります。

  1. ファイル サイズ / 転送サイズは 4294967295 バイトにハードコードされています。そのため、提供されたファイルがそれほど多くない場合、問題が発生します。
  2. 送信者では、ファイルの読み取りが成功したかどうかを確認していません。そのため、ファイルが 4294967295 バイトよりも小さい場合、それがわからず、ネットワーク経由でジャンク データを送信する (またはまったく送信しない) ことはありません。
  3. UDP と DDCP を使用する場合、パケットの順序は保証されないため、受信したデータは順序が乱れる可能性があります (ジャンク)。
  4. UDP を使用すると、失われたパケットの再送信がないため、一部のデータが受信されない場合があります。
  5. 受信側では、受信したバイト数をチェックせず、常に MAX_LINE バイトをファイルに書き込みます。したがって、0 バイトを受け取ったとしても、ファイルに書き込んでいることになりますが、これは誤りです。
  6. UDP を使用する場合、太ももループで送信しているため、write() 呼び出しが要求したバイト数と同じ量の送信バイト数を返したとしても、ネットワーク スタックまたはネットワーク インターフェイスによって多くのデータがドロップされる可能性があります。 、輻輳制御が実施されていないためです。そのため、輻輳制御を自分で行う必要があります。

そして、これはコードを簡単にスキャンしただけです。おそらくもっと問題があります...

私の提案は次のとおりです。TCPで転送を試し、読み取り/送信するファイルのmd5sumと、受信/保存するファイルのmd5sumを実行し、2つのmd5sumを比較します。このケースが機能したら、UDP と DCCP を使用したテスト (引き続き md5sum 比較を使用) に進むことができます...

tcpdump コマンドの場合は、-s 1500for-s 0に変更する必要があります。つまり、unlimited. その tcpdump コマンドを使用すると、表示されていないデータが送受信されていないことを信頼できます。もう 1 つの良い方法は、送信側と受信側の tcpdump 出力を比較することです。これにより、2 つのネットワーク スタック間でパケット損失が発生したかどうかがわかります。

于 2010-07-30T15:20:09.243 に答える
3

x ターム アクセスはありますか? 代わりにWiresharkに切り替えて、それを試してみてください。これは無料でオープン ソースであり、おそらく現在 tcpdump よりも広く使用されています。(以前は Ethereal と呼ばれていました。)

また、次の tcpdump オプションを試してください。

  • -xx パケットのリンクヘッダーとデータも表示します (-w はデータを書き込みますか?)
  • -C 最大ファイル サイズを明示的に指定します。
  • -U は、バッファをフラッシュする代わりにパケットごとにファイルに書き込みます。
  • -p NIC を無差別モードにしない
  • -O パケット マッチング オプティマイザーを使用しないでください。これは、新しいアプリ レベルのプロトコルであるためです。
  • tcpdump で冗長出力を使用していますか? これにより、バッファーがすぐにいっぱいになる可能性があるため、実行時に stdout/err をファイルにリダイレクトします。

これらのギガビット イーサネット カードは両端にありますか?

于 2010-08-01T23:57:24.903 に答える
2

「そのとき、クライアントはファイルをソケットに送信する必要があります。その後、サーバーがファイルの受信とハードドライブへの書き込みを続行しても、ファイルは停止します。」

この音は本当に奇妙です。ソケットバッファが小さすぎるため、これを実行できません。サーバーコードはデータを受信して​​いるように見えますが、送信者は実際にはすでにデータの送信を停止していると思います。

于 2010-08-04T09:19:07.067 に答える
2

tcpdumpは、世界中の何万人もの (少なくとも) プログラマーやコンピューター セキュリティの専門家によって、診断およびフォレンジック ツールとして使用されています。このようなツールが非常に一般的なタスクを誤って処理しているように見える場合、最初に疑うべきことは、ツールではなく、作成したコードです。

この特定のケースでは、コードにさまざまな重大なエラーがあります。特に TCP では、クライアントがデータを送信しているかどうかに関係なく、サーバーはファイルにデータを書き込み続けます。

このコードには、状況によっては非決定論的な動作を引き起こす競合状態があり'\0'、ネットワーク データの特別な値として不適切に扱われ、エラー状態を無視し、ファイルの終わりの状態を無視します。そして、それはほんの短い読み物です。

tcpdumpこの場合、私はそれが完全に機能していて、あなたのアプリケーションがあなたが思っていることをしていないことをあなたに伝えているとほぼ確信しています.

于 2010-08-04T02:52:54.450 に答える
0

これはばかげているように聞こえるかもしれませんが、ファイルの flush() の問題ではないのですか? つまり、データはまだメモリ内にあり、まだディスクに書き込まれていません (十分な量に達していないため)。

sync十分なデータが送信されたことを確認するまで、少し待つか、試してみてください。

于 2010-08-03T10:28:29.910 に答える