マルチスレッドでデータをやり取りする方法とは?

このQ&Aのポイント
  • マルチスレッドでデータをやり取りする方法について悩んでいます。
  • スレッドAで信号を送り、返答があったときにスレッドBを起動し、スレッドAの信号のデータを初期化する方法について、ヒントを求めています。
  • VC6.0で開発している場合、マルチスレッドでデータをやり取りする処理についてアイディアが欲しいです。
回答を見る
  • ベストアンサー

スレッドAで信号を送り、返答があったときにスレッドBを起動、スレッドAの信号のデータを初期化する方法

VC6.0で開発しています。 今、次のような処理をどうすればよいか悩んでいます。ヒントになる回答を頂けたら幸いです。 データをやり取りする際、どのような処理を行うか命令するもの(以下、命令A)と、命令された通りのデータを送るもの(以下、送信B)、そして、AとBの通信部分を担うもの(以下、通信C)があります。 データのやりとりは、マルチスレッドで行っています。 データをやりとりするために、スレッドが通信C上で2つ起動しています。1つ目のスレッド(以下、スレッドA)は、送信Bが命令Aから送られる特定のデータ(以下、データA)を受け取れるかをどうかの信号を、命令Aに送るためのものです。2つ目のスレッド(以下、スレッドB)は、データAを通信Cが受け取り、送信Bに渡すときに起動するスレッドです。 スレッドAで、送信Bから命令Aへ、受信の準備ができたことを伝える信号が送られます。その後、命令AよりデータAが送られ、通信CでスレッドBが起動するのですが、データAを通信Cで受信したとき、スレッドAで送っている信号を初期化しなければいけません。 データAを受信したときにはスレッドBが起動しますので、スレッドAとスレッドBの間での処理ということになります。 スレッド処理について、まだまだ不勉強なのですが、よいアイディアがあれば教えてください。 よろしくお願いします。

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

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.4

アプリ毎に整理してみました。分からないところは想像で書いています。 --命令A-- (1)「命令A→通信C」のファイルを作成。「送信Bが送信Aに対して、データの要求をしているのかを判別するデータを送信しろ」を送る。 (2)「通信C→送信B、命令A」のファイルを監視。「命令Aにデータ要求」が書き込まれるの待つ。 (3)「命令A→通信C」のファイル2を作成。「送信Bの要求データ」を作成する。 (4)「通信C→送信B、命令A」のファイルを監視。「送信Bはデータの要求をしていない」に書き換わるの待つ。 (5)(1)に戻る。 --送信B-- (1)「通信C→送信B、命令A」のファイルを監視。「送信Bが命令Aに対して、データの要求があるか」が書き込まれるのを待つ。 (2)「送信B→通信C」のファイルを作成して、「送信Bが命令Aに対して、データの要求がある」を書き込む。 (3)「通信C→送信B」のファイルが作成されるのを待つ。 (4)ファイルを読んで、データを何らかの手段で送信。 (5)(1)に戻る。 --通信C-- (1)「命令A→通信C」のファイルが作成されるを待つ。 (2)スレッド1を起動する。 (3)「送信B→通信C」のファイルが作成されるのを待つ。 (4)スレッド1に(3)に進むよう指令を出す。 (5)「送信B→通信C」のファイルを削除する。 (6)「命令A→通信C」のファイル2が作成されたことを検出。 (7)スレッド2を起動する。 (8)このあと??? ・スレッド1 (1)「通信C→送信B、命令A」のファイルを作成。「送信Bが命令Aに対して、データの要求があるか」を書き込む。 (2)何らかの指令があるまで(1)を繰り返す。 (3)「通信C→送信B、命令A」のファイルを書き換え。「命令Aにデータ要求」に書き換える。 (4)何らかの指令があるまで(3)を繰り返す。 (5)「通信C→送信B、命令A」のファイルを書き換え。「送信Bはデータの要求をしていない」に書き換える。 (6)「命令A→通信C」のファイルを削除する。 (7)スレッドを終了する。 ・スレッド2 (1)スレッド1に対して、指令を送り(5)に移行するように促す。 (2)「命令A→通信C」のファイル2を読み込み、「通信C→送信B」のファイルを作成する。コピー後「命令A→通信C」のファイル2は削除する。 (3)スレッドを終了する。 勘違いがあったら訂正をお願いします。 全体として問題を感じたので何点か上げます。 ・ファイル作成を条件に動いている所があるが、ファイル内容が全部書き出されていないうちに動き出してしまわないか? ・必要な動作に対してやっていることが複雑である。処理の起点はなぜ送信Bの要求から始まらないのか?命令Aから始まる理由は? ・ファイルの後始末が不明確。 ・スレッド1の処理で、何度もファイルを書き換える理由は? ・命令Aと送信Bが通信していれば作れそうな気がする処理で、通信Cが必要な理由が分からない。 シンプルにするとしたら、こんな感じには出来ないのでしょうか? 一応命令Aを起点にしています。スレッドがなくなってしまうので、このアプリの構成がスレッドの勉強のためだったら申し訳ない! --命令A-- (1)送信Bにメッセージで要求がないか問い合わせる。 (2)送信Bの返事を待つ。 (3)送信要求なら、ファイルを作成する。送信不要なら(1)に戻る。 (4)送信Bにメッセージでファイルが出来たことを知らせる。 (5)送信Bの返事を待つ。 (6)(1)に戻る。 --送信B-- (1)命令Aから要求の問い合わせを待つ。 (2)命令Aにメッセージで要求の有無を送信。 (3)要求無しなら(1)に戻る。 (4)命令Aからファイルの完成メッセージが届くのを待つ。 (5)ファイルを読んで何らかの方法で送信する。 (6)ファイルを削除する。 (7)命令Aにメッセージで送信が完了したことを知らせる。 (8)(1)に戻る。 相互の通信にはWindowsAPIのPostMessageを使用する予定です。 ただし、両方のアプリにhWndが必要なので両方ともウィンドアプリである必要があります。 http://yokohama.cool.ne.jp/chokuto/urawaza/api/PostMessage.html

wweerr
質問者

お礼

返信が遅くなり申し訳ありません。 こちらの方でいろいろ考えた結果、2つのスレッドで考えるより、一つのスレッドで工夫した方がよいということになりました。 zwiさんには、私の分かりづらい説明に付き合っていただいて、ありがとうございました。

その他の回答 (3)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

すいません。今読んでところなのですが。 >3.送信Bが、データを要求します。 これって、どうやって伝えていますか?

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

すいません、まだ複雑でした(^^ゞ 問題なのは、データの流れがいまいち掴めないことです。 流れの順番で書いてもらえませんか? 私なりに分かっていることを想像を交えて書くと。 (1)「通信C」のスレッド「通信Cから命令Aへ」が命令Aへの通信ファイルで「送信Bがあるデータの送信を命令Aに要求している」を書き込む。 (2)「命令A」が(1)の指令を見て送信Bに送るデータファイルを作成する? (3)「通信C」のスレッド「???」が「命令A」が作成したデータファイルを発見して「送信B」に「送信Bで送信してほしいファイルがあるよ」という意味のファイルを作成する。 (4)「送信B」は、「送信Bで送信してほしいファイルがあるよ」を見つけたら「命令A」の作ったファイルをなんらかの通信で何処かに送出する。 (5)送信処理の後始末「信号データの初期化」を行う。 って事でしょうか?(1)の前のデータ送信の起点がよく分からないのですが、どのプログラムが送信を要求しているのでしょうか?送信Bです? 印象としては、妙に複雑なことをしている気がします。もっとシンプルに作れそうな感じがするのですが、とりあえず流れが分からないとアドバイスできないので、詳細にお願いします。

wweerr
質問者

補足

すいません。補足します。 1.命令Aが、命令Aから通信Cへ「送信Bが送信Aに対して、データの要求をしているのかを判別するデータを送信しろ」という命令を保存したファイルを共有ディレクトリに保存します。 2.通信Cが「1.」のファイルのデータを読み込み、送信Bが命令Aに対して、あるデータの送信を要求しているかどうかを示すデータを共有ディレクトリに保存します。「1.」で保存したファイルとは別のファイルに一定周期で上書き保存を繰り返します。この処理のために、スレッドが一つ起動します。命令Aは、このファイルを監視して、常にデータをチェックしています。 3.送信Bが、データを要求します。 4.通信Cが、送信Bがデータを要求していることを示すデータを、「2.」で保存したファイルに書き込みます。今後は、初期化されるまで、データ要求を意味するデータを保存し続けます。 5.命令Aが、データ要求を意味するデータがきたことを検出します。 6.命令Aが、要求されたデータを書き込んだファイルを、共有ディレクトリに保存します。 7.通信Cが「6.」で保存されたファイルを検出し、データを読み込み、送信Bにデータが送られます。この処理のために「2.」とは別のスレッドが一つ起動します。 8.「7.」のスレッドが起動すると同時に、「2.」で起動したスレッドでは、ファイルに保存するデータを「送信Bはデータの要求をしていない」という意味のデータを保存するようにします。つまり初期化です。 こういった感じなのですが、うまく伝わったでしょうか? 回答をよろしくお願いします。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

ごめんなさい。説明が良くわかりません。他に返答がないのも、それが原因だと思います。命令AとかスレッドAとか???です。 どこまでが1つのプログラムなのか、関数の単位はどこまでか、A,B,C間ではデータをどうやって受け渡しているのかなど疑問がいっぱいです。そもそも信号って、signalのこと? で、状況を整理したいと思います。 やっていることの細かい説明はおいておいて、何をやりたいかとスレッド化している理由を説明してもらえないでしょうか。 信号のデータを初期化するという言葉の意味も。

wweerr
質問者

補足

すみません。質問が大雑把+内容に抜けが多すぎたようです・・・(反省) データは、ファイルでやりとりしています。 共有のディレクトリがあり、そこにファイルが保存されます。ファイルデータを読み込むのは、命令A、通信Cと名前をつけたアプリケーションなのですが、ファイルの種類によって、どちらがデータを読み込むかが決まります。 例えば、拡張子がAAAとついたファイルなら、通信Cがディレクトリに保存し、命令Aが読み込むといった感じです。 1.スレッド化している理由 命令A、送信B,通信Cそれぞれが、一つのアプリケーションです。スレッドは通信Cで作成されます。通信Cの中の一つのクラスが共有ディレクトリにファイルが保存されたかを監視しています。ファイルが保存されると、このクラスがファイルを読み取り、そのデータに対応した関数を実行します。この実行される関数が、それぞれスレッドとなります。データごとに処理を行う必要があるので、マルチスレッドで処理しています。 2.信号データの初期化 一つのスレッド処理で、通信Cから命令Aに対して、「送信Bがあるデータの送信を命令Aに要求している」かどうかを意味するデータを、共有ディレクトリに保存し続けています。 信号データの初期化とは、送信Bが、命令Aからのデータを通信Cを経由して受け取ったあと、共有ディレクトリに保存するデータを、「現在、送信Bはデータの要求を行っていない」という意味のデータに変更するということです。 3.何をやりたいのか 「信号」データを保存し続けている処理と、データを受信する処理は別スレッドで処理されています。 「信号の初期化」を行うタイミングは命令Aが共有ディレクトリにファイルを保存し、これを通信Cが検出し、送信Bにこのファイルのデータを送るスレッドを起動したときです。 別々のスレッド間での処理になるので、このタイミングで、どう「信号」データの初期化を行えばよいかで悩んでいます。 長々と書いてしまいました。zwiさんが知りたいことに対してきちんと回答できているか不安ですが、回答をよろしくお願いします。

関連するQ&A

  • 親スレッドが子スレッドを監視する方法について(マルチスレッド)

    こんにちは。 私は、A端末から送信されたパケットをB端末で受信し、B端末で受信したそのパケットを再度、A端末へ送信するというプログラムを作成しました。 Phase1.A端末(送信側)→B端末(受信側) Phase2. B端末→A端末 ということです。 上記を実現するために、送信端末において、送信スレッド(親スレッド)と受信スレッド(子スレッド)を立てマルチスレッド処理を行っています。以下にプログラムの概要を示します。 main(int argc ,char *argv[]){ UDPSend(s_port,szServer); } static int UDPSend(unsigned short s_port,char *szServer){ hTh = (HANDLE)_beginthreadex(NULL, 0, UDPReceiveData, NULL, 0, &thID); while((n = fread(send_Buf,1,SEND_DATA_SIZE,fp)) != 0) { sendto(s1, send_Buf, n, 0, (LPSOCKADDR)&addrin1, sizeof(addrin1)); } } unsigned __stdcall UDPReceiveData(void *lpx){ while (1) { size = recvfrom(s2, recv_Buf, (int)sizeof(recv_Buf) - 1, 0, (SOCKADDR *)&from, &fromlen); return 0; } } UDPSend関数にて、パケットをB端末へ送信。UDPReceiveData関数にて、B端末からのパケットを受信しています。この場合、UDPSend関数(スレッド?)がUDPReceiveData関数より先に、終わってしまう場合が生じると思っているのですが。 UDPSend関数がUDPReceiveData関数を監視する方法があるのでしょうか? よろしくお願いします。

  • [C#/.NET2.0] 状況によりスレッドを実行しないで終える方法

    [C#/.NET2.0] 状況によりスレッドを実行しないで終える方法 こんにちは、お世話になってます。C#と.NETでプログラムを組み始めて2週間程度の初心者です。C/C++カテ違いっぽくてごめんなさい。 マルチスレッドの制御で悩んでいます。ファンクション(func)が、複数のスレッド(a,b,c,…)で起動されます。スレッドは、デバイス入力を処理し起動されるため、順不同で非同期(というのかな?)です。この時、あるスレッドによりfuncが処理中であれば、他のスレッドは待機しないで終了する。というような排他的処理を作りたいと考えています。たとえば、bが起動されているときは、aやcのスレッドが起動されても、待機せずに終了するような感じです。 試しに下記のような仕組みを考えてみました。 01:object key_syncer = new object(); 02:volatile bool key_locked = false; 03: 04:void func() { 05:  //===== Gate ===== 06:  lock(key_syncer) { 07:    if(key_locked) return; 08:    key_locked = true; 09:  } 10: 11:  //===== Function Body ===== 12:    /* Some behavior */ 13: 14:  //===== Exit ===== 15:  lock(key_syncer) { 16:    key_locked = false; 17:  } 18:} とりあえずは動いているのですが、マルチスレッドの作法に未熟で自信が無いです。スレッドセーフを意識したり、「普通こう書くだろ?」というような作法もわかっていません(汗)。上記の様な書き方の良否や、異なる書き方などありましたら、アドバイスいただけるとうれしいです。よろしくお願いいたします。

  • 非同期プログラミングは必ずマルチスレッド?

    非同期プログラミングは必ずマルチスレッドプログラミングになりますか? ここでいう非同期プログラミングとは、 何かのメソッドを実行してその処理(処理Aとする)の結果を待たずに次の処理Bを実行できて、処理Aが終わったらコールバックやデリゲートで、あらかじめ決められたメソッド(finishとする)が呼ばれるといったものです。 処理Aを実行するメソッドを呼ぶ ↓ すぐに処理Bを実行開始(このときバックグラウンドで処理Aが走っている) ↓ 処理Aが終了したのでfinishメソッドが実行される 例えば、Objective-CのNSURLConnectionで非同期通信するときのようなやつです。 こういった非同期プログラミングは、必ずマルチスレッドを使うことになりますか? 普通、別スレッドで処理させるときはスレッド用のライブラリを使うなどして明示的にマルチスレッドプログラミングをしますが、上のように非同期のメソッドを使うと、その裏で自動的に別のスレッドが動くのでしょうか。 それとも、単一スレッドのみで、非同期プログラミングできるでしょうか。 なお、特殊な言語やOSによっては、いくらでも可能性があると思いますので、 メジャーな環境(Windowsや、スマホ) のみに限定してお願いします。言語で言うと、C、C++、Objective-C、Javaあたり。 また、上の「処理A」が終わったとき、メソッド「finish」が呼ばれるとすると、 処理Bの実行中にどのようなタイミングでfinishが呼ばれるのでしょうか。 処理Bはどのような形でfinishに切り替わるのでしょうか。いきなりfinishに処理を奪い取られるのでしょうか

  • ワーカスレッドAfxBeginThreadのスレッド起動を遅延させたい

    アラーム情報などをBASP21を用いてE-Mail送信するプログラムを マルチスレッドにしていました。 自己メールサーバーを立てていた場合は、1秒間に何件でもセッション 張ってもよかったのですが、訳あってOCNのメールサーバーを使うように したところ、1秒間に複数のセッションを張ると迷惑メール送信 と認識されるため、接続が拒否されていまいます。 そこで、マルチスレッド化しているアラームメールの起動間隔を伸ばす ためにAfxBeginThreadの後に Sleep( 5* 1000 ); を入れて1秒間に複数送信しないようにしたつもりなんです が、何故かSleepが効かな状況です。 エラー内容としては、次のように表示されます。 Too Many Session 421 細かく見ていくと、状況によって次のエラーでした。 http://homepage1.nifty.com/yito/anhttpd/winsock_error.html 10060 WSAETIMEDOUT 10061 WSAECONNREFUSED Connection refused ログを見てもスリープが効いておらず、間隔なしにアラームメールが 1秒間に10件近く送信されてしまいます。 一応渡されたスレッドの最後に AfxEndThreadを書いてみたり書かないようにしてみたんですが、 状況は変わらずです。 #include "stdafx.h" #include "windows.h" for( i=0;i<ALARM_MAX;i++ ){ m_pThreadCL[i] = AfxBeginThread(ThreadProcCL, (LPVOID)i,THREAD_PRIORITY_NORMAL) Sleep( 5 * 1000); //::Sleep( 5 * 1000 );の間違い? } 念の為 スレッド起動をしなければいいのですが、単純にはいかなかった ため、応急処置としてスレッドの起動間隔を遅延させる方法を どうにかできないものでしょうか。あくまでも応急処置として、 お願いいたします。

  • c# スレッド間でのデータの共有

    C#でメインプロセスと生成されたスレッド間でデータの共有をさせたいのですがどのようにすればいいのでしょうか。ご教授お願い致します。 ・メインプロセス(A) ・Aから生成されたスレッド(B) 例えば、AとBで変数の値をそれぞれ読み書きさせたい場合 どのようにすればよいのでしょうか。 class TEST { public int flag; // メインプロセス(A) public static void Main() { Thread t = new Thread(new ThreadStart(abc)); t.IsBackground = true; t.Start(); while(ture) { Thread.Sleep(10); Console.WriteLine("A:{0}",flag); } } // Aから生成されたスレッド(B) public void abc() { Console.WriteLine("B:{0}",flag); flag++; } }

  • Xcodeでマルチスレッドでなく順処理する方法

    こんにちは。 今Xcode4.2.1を使っております。 さて、今処理としてあるアプリ連携を行う処理を作っているのですが、 マルチスレッドでなく 「処理A」→「処理B」→「処理C」 と順に処理をしたいのですが、スレッド化してうまくいきません。 具体的には [self presentModalViewController: controller animated: YES];(処理A) [処理B] [処理C] : と書いた時に、処理Aがスレッドとして動くので、 処理Aが終了しないうちにB、Cがスタートしてしまいます。   1)順に処理をさせたい(マルチスレッド化しない方法)のですが、     どうやったらよいのでしょうか? もしくは   2)Aの処理がおわるまで監視&制御する(排他制御)方法はあるのでしょうか? 素人質問で申し訳ありません。 些細なことでも結構ですので 宜しくお願い致します。

  • CSocket通信での待機処理について

    VC++2008にて、サーバとクライアントPCにて、相互通信を行うプログラムを作成しています。 クライアントは、CSocketを利用しマルチスレッドにて通信を行っています。 thread_start→マルチスレッド作成→ CSocket::Sendでサーバへメッセージ送信→ CSocket::OnReceiveでサーバのメッセージ受信→ サーバメッセージから処理実行と言った流れです。 通常の処理は、この流れで問題ないのですが、 ある処理の場合、thread_startをforループで数回繰り返す 処理を行っています。 この時、データにタイムラグが出てしまうため、 thread_startから処理実行までの一連の流れが終了するまで、 次のthread_startは呼ばれずに待機させたいのですが、 どのようにすれば良いのかが分かりません。 Sendを呼んだタイミングで、 WaitForSingleObjectでスレッドのハンドルを渡したり、 CreateEventでイベントハンドルを渡したりしてみたのですが、 WaitForSingleObjectを呼ぶと、OnReceiveで受信する前で 止まってしまうため、そのままフリーズ状態になってしまいます。 どのタイミングでWaitFor~を呼ぶべきなのか、 もしくは、何か別の手段があるのでしょうか?

  • スレッドの一時停止と再開について

    こんばんは。 VC++.NET2003でC言語にて、UDPソケットプログラミングを行っています。 A:送信端末 B:受信端末 とし、送信端末から受信端末へ各パケットにシーケンス番号を付加し1024Byteずつパケットを送信。受信端末は、送信端末からのパケットを受信するのですが、受信できなかったパケットがある場合、シーケンス番号を送信端末へ送信します。 これらから、送信端末は、送信と受信スレッドを持つ、マルチスレッドを行っています。 以下に送信端末のプログラムを示します。 main{  //受信スレッド生成  hTh = (HANDLE)_beginthreadex(NULL, 0, Sequence_Number, NULL, 0, &thID);  UDPSending(s_port,szServer);  //受信スレッド終了待ち  WaitForSingleObject( hTh, INFINITE );  CloseHandle(hTh); } //送信スレッド UDPSending(s_port,szServer){  //fread関数にて、1024Byteずつ区切る  while((n = fread(send_Buf,1,SEND_DATA_SIZE,fp)) != 0) {   UDPDataSend(s_port, szServer, send_Buff, n+mojisuu);  } } UDPDataSend(unsigned short s_port, char *szServer, char *send_Buff, int n){   sendtoにて受信端末へ送信 } //受信端末からの未受信シーケンス番号を受信(受信スレッド) unsigned __stdcall Sequence_Number(void *lpx){   recvfrom関数によりシーケンス番号を受信 } [付け加えたい機能] 送信スレッドにおいて100個のパケットを送信したら、一時的に送信スレッドを停止させ、受信スレッド内の処理を行い、受信スレッド内の処理が終えたら、再度、送信スレッドを再開させる方法はありますでしょうか? イメージでは・・・ S:送信スレッド R:受信スレッド とした場合、 S(100個パケット送信)→Sの休止→Rの処理→Rの処理が終えたら→Sの再開(再度100パケット送信)・・・・ の繰り返しです。 よろしくお願いします。

  • UART通信で2つの信号を同時に伝送したい

    UART通信において,図に示すように,送信者A・Bからそれぞれ信号を同時に伝送し, 受信者Cに伝送したいと考えています。 現時点で考えている方法として,図(下)のように,送信者Aの信号を正,送信者Bの信号を負と して伝送し,受信者は,それを結合した信号を受け取ることで,同時に2つの信号を伝送しようと 考えています。しかしこの方法では,変調器をA/B/Cそれぞれに導入する必要があるため, コストがかかるというデメリットがあります。 そのため,このような操作をソフトウェアだけで実現できないかと模索しているのですが, 通信の知識が乏しいため,よい方法を思いつきません。 何かよい方法はないでしょうか? アドバイスお願いします。

  • TCP通信のブロッキングについて

    初めて投稿させて頂きます。 javaでTCP接続での4人で遊ぶ大富豪を作っております。 サーバーを用意し、各ユーザーがサーバーに接続して遊ぶタイプです。 サーバーの構造は次のようになっております。 ・クライアントから接続を受け付ける待機クラス(Server.java)を常時走らせておく ・待機クラスに接続があれば、1ユーザーごとに送受信のスレッド(client.java)を立ち上げる。各ユーザーからのデータはこのクラスが受け取る ・人数が4人集まれば、テーブルスレッド(table.java)を立ち上げる。各ユーザーと接続されているclient.java(*4)がデータを受け取るとここが計算を行う 各ユーザーがサーバーに接続し、データのやり取りをするところまでは成功したのですが、以下の事について色々調べたのですが分からず、教えて頂けると幸いです。 (質問)ユーザーの接続が切断されたときのTCPの動作について 例えばABCDの4人のプレイヤーが居て、A→B→C→Dの順番だとします。今Aが◇3を切ったとします。するとAから「◇3を切った」というデータをサーバー(サーバーが発行したAとの送受信クラス)に送信し、サーバーが受信、それをABCD全員に送信して手番がBに移ります。この時、仮にCが切断されていてABCDにデータを送信したけどCだけデータが届かない、というケースの場合について、全員のデータの整合性を取るために「サーバーが、"Aが◇3を切った送信"に対するACKパケットを全ユーザーから受信したのを確認してから手番をBに移す」という手順を踏みたいのです。 各クライアントとの送受信のスレッドは余計なところは省略すると以下のようになっております。 class client implements Runnable{ (変数宣言) (コンストラクタ) public void run(){ while(true){ try{ ※(1) in.read(b); // inはSocket.getInputStreamの戻り値 (データを受け取ったことで色々な処理) out.write(b); // outはSocket.getOutputStreamの戻り値 out.flush(); ※(2) }catch(Exception e){} } } } Aと接続されているclientクラスのin.readで「◇3を切った」を受信し、色々な処理を行った後、ABCDと接続している各clientクラスのout.writeで「◇3を切った」を送信します。 ここで質問なのですが、接続が途切れているCの場合、out.write(b)の部分ACKパケットを受信するまで何度もリトライをすると思うのですが、プログラムの動作としてはリトライをしながらもout.write(b)以下の処理に進んでしまうのでしょうか?それともACKを受信するまでここでプログラムはブロックされるorタイムアウト等が発生するまでリトライorサーバーが即切断を認識してExceptionに移行する のでしょうか?私の希望としては例えば上記プログラムの※(1)にf=false;(fはboolean)、※(2)にf=trueなどを置いて「全スレッドのf==trueになれば、次の作業をしてもOK」という風に出来ればプログラム的に楽なのですが、接続が途切れているプレイヤーCのスレッドはout.writeの結果に関わらず(リトライされようが)下の命令を実行してしまうのでしょうか?「ACKパケットを受け取ったか否か」を判断したいのですが、プログラムの動作としては パケットを受け取った/受け取ってない で、どのように差が出るのでしょうか。また、out.writeの内容に関わらずプログラム処理が進んでしまう場合、どのようなプログラムが最適でしょうか。 このサンプルの場合だと、Cとの接続クラスはin.readのところで確実にブロックされますが、もしout.writeでブロックされなければACDのプログラムはBを放っておいてどんどん先に進んでしまい、データの整合性が怪しくなってきます。 詳しい方居られましたらお教え頂ければ幸いです。

専門家に質問してみよう