• ベストアンサー

受信処理の終了条件

TCP通信でデータを送受信してスループットを測定するプログラムを作成しました。 1.ホストAがデータを送信し,ホストBがそれを受信し、スループットを計算する. 2.ホストBがデータを送信し,ホストAがそれを受信し,スループットを計算する. 3.ホストAがホストBにfinishという文字列を送信する. 4.ホストBがホストAにfinish_recvを送信する. 5.プログラムを終了する. 1と2を行った後,測定終了しましたという意味のfinishをホストAからホストBに送信させます。 ホストAの動作が何らかのアクシデントで2.の途中、つまり受信処理中に止まってしまった場合, ホストBはfinishを受信するためにずっと受信状態で待つことになるとおもうのですが, ホストAは止まっているので,finishが受信されずに永遠に受信待機になると思います. このように何らかのアクシデントで受信処理が終わらなくなった場合、受信しなくても 強制的に受信処理を終わらせることはできますか? 私が考えたのは時間内にデータが送信されてこなかったら強制的に受信を止めさせるというものです. なにかよい方法はありませんか?アドバイスをしていただきたいです.

  • Java
  • 回答数1
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

強制的に受信処理を終わらせることはできます。Socketをshutdownあるいはcloseすれば強制的に受信処理を終わらせられます。 また、debukawaさんが考えておられる通り、一定時間待っても通信がなされなかったら何らかのアクシデントのために通信できなくなったと判断して通信を切断するというのが一般的だと思います。SMTPなどインターネット上で使われている主要なプロトコル(約束事)にもどれくらいの時間待たなければならないかが明記されているほどです。この待ち時間のことをタイムアウト時間と言います。 Javaでタイムアウトを使うには、SocketクラスにあるsetSoTimeoutメソッドでタイムアウト時間は設定します。設定したあと受信(read)中にタイムアウトが発生すると、java.net.SocketTimeoutExceptionが発生しますのでそれをcatchすれば一定時間受信がなかったことがわかります。なお、setSoTimeoutをしていないとそのプログラムはデータがくるまで待ち続けます。(マルチスレッドだとデータを待っているスレッドだけが止まりますが...)

debukawa
質問者

お礼

hanabutako様,回答ありがとうございます. 参考にさせていただきます.

関連するQ&A

  • メッセージを受信したら受信終了したい

    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点を絶対に削りたくないのです。 どうすればよいか、アドバイスをいただけないでしょうか?

    • ベストアンサー
    • Java
  • UDPで受信終了の合図を出して受信終了させる

    UDPの帯域測定プログラムを作成しています。 100個のパケットを受信した後、受信処理を終了させるのに、 endの文字を挿入したパケットを受信することで受信を終わらせようと考えています。 パケットを送信する側は100個のパケットを送信し終えたら、endのパケットを送信します。 受信側はendのパケットを受信したら受信を終了します。 受信側がendを受信したら送信側がendのパケットを送信するのを止めさせたいのです。 UDPではパケットが消失するため、送信側は受信側がendを受け取ったことを確認したあとに送信をやめなければなりません。 endを受け取ったら、合図を返信すればよいと思いますが、その合図が消失することもあるので、「endを受信したら合図を返信する」という処理を終わらせるタイミングも分かりません。 どのようにしてendを受け取ったことを確認すればよいでしょうか?

    • ベストアンサー
    • Java
  • UDPで受信スループットを測定

    Javaを使って通信のプログラムを勉強しています。 UDP通信のスループットを測定するプログラムを作成しています。 送信側で5242880バイトを128回に分割して送信して、 受信側でそれらのパケットを受信する時間を計測するプログラムを 作りたいのですが、受信側でどのタイミングで受信処理を止めるのかがわかりません。 start = System.currentTimeMillis(); for(;;){   socket.receive(RecvPacket);   if(ループを抜ける条件)     break; } stop = System.currentTimeMillis(); で受信し続けて、受信するパケットがなくなったらループを抜けるというように考えました。 UDPでは送信されたパケットがすべて届くという保証はないので、 128回受信したらループを抜けるというようにできないので、困っています。 届いたパケットの数も数えて到達率も計算したいです。 受信が終わったら、ループを抜けるというようにしたいのですが、 どうすればよいでしょうか?

    • ベストアンサー
    • Java
  • メールを受信すると不正な処理で強制終了

    OKwebのメールを受信するとある質問のところで必ず強制終了されてしまいます。 データ量が多いのかとこまめに受信しては削除しましたが、やはりある質問で強制終了です。 現在outlookが開くと自動的に受信するので即強制終了という事態に陥っています。 サーバーから削除でもいいので何か解決策はあるでしょうか。

  • メールの受信ができません

    昨日の夕方から突如、Outlookでのメール受信ができなくなりました(送信の方はできます)。 過去の「OK Web(教えてgoo)」も参考にしながら、色々試してみたのですが、「このプログラムは不正な処理を行ったので強制終了されます」と出るばかりです。不正な処理などやった記憶はないのですが・・・。 どうすればいいのか、教えて下さい。

  • 例外処理の付け方

    javaを使って通信のプログラムを作成しています。 ホストAで送信データを作成し、そのデータをホストBに送信して、 ホストAが送信するのにかかった時間と、ホストBが受信するのにかかった時間を 計測するプログラムを作成しました。 送信と受信の処理を行うのですが、送信側では、write()でバッファに書き込んで、 fulsh()で書き込まれたバイトを出力ストリームに書き込みます。 受信側では、while((ch=in.read()) != -1)で送信データをすべて読み込ませます。 write()、fulsh()を使って送信し、read()で受信するのですが、 これらのメソッドが正常に動いたかどうかを調べたいのです。 ネットで方法を調べたのですが、try catchを使うことで例外処理が発生したら、 エラーを出力させることができることがわかりました。 もしurite(),fulsh(),read()が正常に起動しないならエラーを出したいのです。私なりに考えて以下のようにしました。 コードは以下のとおりです。送信部分、受信部分です。 送信側 int count = 0; // write()の回数 System.out.println("<データ送信処理>"); start = System.nanoTime(); // 計測開始時間 for (int i = 0; i < Data - 2; i++) {   try {     out.write(i);     count++;   } catch (IOException e) {     System.out.println(i + ":書き込みエラー");   } } try{   out.write('\\'); }catch(IOException e){   System.out.println("\\" + "書き込みエラー"); } try{   out.write('s'); }catch(IOException e){   System.out.println("s" + "書き込みエラー"); } count = count + 2; out.flush(); stop = System.nanoTime(); // 計測終了時間 System.out.println("送信完了"); 受信側 while (ch != -1) {   try{     ch = in.read();   }catch(IOException e){     System.out.println("読み込みエラー");   }   Count++;   if (ch == '\\') {     on = true;   } else if (on == true && (char) ch == 's') {     stopNs = System.nanoTime();     System.out.println("受信終了時間を確認");     break;   } else if (on == true && (char) ch != 's') {     on = false;   } } メソッドが正常に起動しない場合は、例外処理を行うということを したいのですが、上の方法は正しいのでしょうか? このようにして実行しても、「入力エラー」と言う表示はされません。 もしかしたら、ただ異常な動作が行われていないから、そういったエラーが 表示されないのかもと考えましたが、例外処理の書き方が違う可能性があると思い、 質問させていただきました。 どなたかアドバイスしていただけないでしょうか?

    • ベストアンサー
    • Java
  • プログラム終了時のデータ送信処理@VB6

    プログラム終了時のデータ送信処理@VB6 複数のフォームがあり(A-Z)プログラム終了の際はどのフォームがアクティブであっても、 かならずフォームAをアンロードするようにプログラムされています。 フォームAにはWinsockコントロールが2個使われておりフォームがアンロード(UnloadまたはUnloadQuery)される際には相手先にCLOSEとDISCONNECTを送信するようにくみます。 このときに、 送信コマンドをForm_QueryUnloadイベントに組み込んだところデータが送れませんでした。 もちろんForm_Unloadでも送れませんでした。 アンロード時にデータを送信するにはどうすればよろしいでしょうか? ご助力お願いします

  • 複数の処理の終了を待ちたい

    お世話になります。以下、教えていただけますでしょうか? バッチファイル(A.bat)を作成しています。 そのなかで、a,b,c,dの複数のプログラムを、前処理の終了を待たずに起動させ、a,b,c,d全てが終了するのを待って、eというプログラムを実行させたいのです。 --------------- start a start b start c start d --------------- この記述で、a,b,c,dが一度に起動することは確認できました。 しかし、この後の、「a,b,c,d全ての終了を待ってeを起動させる方法」というのが分かりません。 教えていただけますでしょうか? それとも、そもそも、バッチでは実現不可能なのでしょうか?

  • USB機器からのデータ受信による割り込み処理について

    お世話になります、fujitomoです。 まだ実際にプログラムのコードを開発しているわけではないので、漠然としたイメージでの質問となるのですが、質問させて頂く内容は USB機器で取得した測定データを、USB機器からアプリケーション(C++ MFCにて開発)に送信し、受信時に割り込み受信の処理をし、そのUSB機器から送信されたデータをリストやダイアログ上に表示させたいと思ってるのですが、その実際の実装方法の流れを教えていただければと思い、質問いたしました。 シリアル通信と同様にUSB用の割り込み受信関数といったようなものがあるのでしょうか? 全体の流れのイメージが掴めず、どこから着手していいか分からないため、ご存知の方がいらっしゃいましたら、ご回答宜しくお願い致します。

  • 終了処理ができない

    システムが不安定になりいろいろアドバイスを受けて改善されて来たのですが、最後に以下の問題が頻発します。終了処理して電源を切ろうとしても 「このプログラムからの応答がありません。ビジー状態か、入力待ちか、停止しています」のメッセージが出て 終了を選んでも強制終了されず、正常シャットダウンが 出来ずやむなく電源ボタンの長押しで電源を切り終了させている状態です。このプログラムというのATOK15UIとの表示があります。検索するとATOK15UI.DLLというのがそれに当たるようです。対処方法ありましたら教えてください。

専門家に質問してみよう