プロが教える店舗&オフィスのセキュリティ対策術

TCPでスループットを測定するプログラムを作っています。

データの受信を終了するには、送信側がソケットをクローズして、
受信側のread()メソッドが-1を返すのが主流だと考えていますが、
私のプログラムでは、受信した後に受信側から送信側へデータを返信したいため、
ソケットをクローズすることで受信終了というようにしたくないです。
また、受信したバイト数をread(buf,int,int)の戻り値で取得したいです。

私が考えている方法としては、送信側で「finish」というメッセージを送信したら、
受信側で受信を終了させようと考えました。

read(buf,int,int)はbufに受信したバイトを格納すると思います。格納されたバイトの最後から6個を確認させ、
finishならば受信終了にすればよいと考えました。

送信側のコードは下のようにしました。
String signal = "finish";
byte[] signal_buf = signal.getBytes();

send_start = System.nanoTime();
for (int i = 0; i < Data-6; i++) {
  try {
    out.write(i);
    out.flush();
  } catch (IOException e) {
    System.err.println(e);
  }
}
out.write(signal_buf);
out.flush();
send_stop = System.nanoTime();
System.out.println("送信完了");

受信側は、finishを読み込んだらループを抜けるようにしたいです。
recv_start = System.nanoTime();
for(;;){
  part = in.read(buf);
  if(part > 0)
    total += part;
  if(finishを読み込んだら){
    break;
  }
}
recv_stop = System.nanoTime();

どのようにしてfinishを読み込んだことを認識させれば良いでしょうか?
・合図となるメッセージにより受信を終了すること、
・read(buf,int,int)の戻り値で読み込んだバイト数を取得すること、
この2点を絶対に削りたくないのです。

どうすればよいか、アドバイスをいただけないでしょうか?

A 回答 (2件)

UDPは非常に信頼性の低いプロトコルですので、TCPの場合と同様の電文を送受信しても期待したデータを確実に受け取れる保障はありません。


UDPでは、
・connectに成功しても、相手プロセス(受信側ポート)が存在しているかどうかは不明
・受信バッファが足りなかった場合に、パケットが破棄されて、エラーかどうかの判別もつかない
・一部パケットをネットワーク上で失っても、分からないことがある
のようなことが当然のように発生します。

ですのでUDPでは、(たとえば単なる通知メッセージなどのように)失っても処理に影響を与えないようなもののみを送受信するようにして、
しっかりと送受信したいデータはTCPで送受信するべきだと思います。

性能測定の場合、受信したデータグラムの受信サイズと受信時刻とかをprintするようにして、その時間間隔とサイズを見るぐらいでしょうか。いずれにしても、あまり確実な計測方法は期待しないほうがいいと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

送信データをUDPで送信した後、TCPで受信終了させる合図を
送信するという仕組みにしたところ、うまくできました。

アドバイスをしていただき、ありがとうございました。
また、分からないところがあれば質問させていただきますので
よろしくお願いします。

お礼日時:2009/12/15 15:55

このままだと最後の"finish"が一回のreadで取得されかった場合に、終了の判定ができいことが発生します。


小さいデータサイズであれば、たいてい一回のreadで全部取得できることが多いのですが、しかしその保障はありません。
"finish"を送る直前にflushすると、"finish"は一回で受信できる可能性はそれなりに高まりますが、間にレイヤ3ハブなどが入ったりすると、やはり保障はありません。
アプリケーションレベルの電文形式を決めて、送受信するのが一般的でしょう。

たとえば、
データ電文 = コマンド("DAT") + データ長 + データ
終了電文 = コマンド("FIN")
終了応答電文 = コマンド("ACK")
などと決めておいて、

・送信側
1.データ電文送信
2.終了電文送信
3.コマンド(終了応答電文)のデータサイズ分(例えば3byte)に達するまで繰り返し受信

・受信側
1.コマンドのデータサイズ分(例えば3byte)に達するまで繰り返し受信
2.データ電文の場合には、
2-1.データ長をデータ長サイズ分(例えば4byte)に達するまで繰り返し受信
2-2.データをデータ長分に達するまで繰り返し受信
3.終了電文の場合には、終了応答電文を送信して、プログラムを終了する

というふうにすれば、確実に終了電文を判定できるでしょう。
終了電文での終了か、切断での終了かをprintしておけば、なお確実に確認できます。

また、データ電文を一定サイズに分割送信してみたり、分割サイズを変えてみたりして、性能にどのような影響がでないのか?でるのか?、また、ネットワーク構成をかえるとどうか?、何でそうなるのか?などを探ってみるともっと面白い性能テストができるかもしれませんね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

TCPとUDPのプログラムを作っています。TCPの方はアドバイスをしていただいたおかげで完成しました。

UDPがうまくできません。UDPもおなじようにやればよいのでしょうか?

お礼日時:2009/12/13 11:51

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!