• 締切済み

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

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

みんなの回答

  • wathavy
  • ベストアンサー率22% (505/2263)
回答No.1

Event を set する関数が、待っている関数の下で呼び出されていませんか? たまに、関数の上下関係が原因で、WaitForSinlgObjectが無限に待ってることがあります。 テストで、階層の高い位置でSetEventしてみて、フリーズ解除できるかどうか確認してみてください。 もし、動作するようならば、構造を変える必要があります。 どんな構造でどうやってるのかすら、想像できませんけど。

lhouse
質問者

お礼

Sendした後は、サーバがメッセージを送信すると、 自動でOnReceiveに入ってくるので、 特に何の処理も入れてなかったのですが、 Send後に、selectで受信可能になるまで待機させ、 可能になったらOnReceiveを呼ぶようにすることで、 SendからReceiveまでを一つの継続した流れで処理することで 解決しました。

lhouse
質問者

補足

CreateEventはthread_startを呼ぶ関数にて。 WaitForSingleObjectは、Sendを呼んだ後で。 SetEventはOnReceiveの最後に呼んでいますので、 合っていると思われます。 構造を変えるというのは、 通信手法を変えるということでしょうか?

関連するQ&A

  • 受信待機

    こんばんは。 現在通信機能をもつアプリケーションを作成しています。 CSocketを使用して、同期通信です。 質問です。 クライアントから、サーバにメッセージを投げます。 するとサーバはこのメッセージを解析して、ローカルで処理をし、その結果をクライアントに返します。 問題なのは、クライアントでは、サーバからの結果を受信してからその次の処理を行いたいので、受信待機したいのですが、その方法がわからないのです。 このような処理の方法をご教授ください。 よろしくお願いします。

  • TCP通信による1サーバ、複数クライアントモデル

    TCP通信による1サーバ、複数クライアントモデル(チャット等)をwinsockを使用して作成したいのですが、複数のクライアントからサーバにアクセスする方法がわかりません。マルチスレッドで、クライアントからの受信待ちスレッドと、ログイン中クライアントへのメッセージ送信スレッドが必要(?)なんでしょうか?また具体的なソースなど掲載されているページがありましたら教えてください。

  • WaitForSinbleObjectについて

    こんにちは。 現在VC++6.0でスレッドを用いたプログラムを行っています。 GUIでSTARTボタンを押すと、ワーカースレッドが起動し特定量の処理を開始します。(例えば100件のファイルコピーなど) 100件の処理が完了したらワーカースレッドは終了する。 GUIでSTOPボタンを押したときにフラグを立てて、ワーカースレッド内でそのフラグが立っていたら処理を抜けてスレッドを終了させることもできるようにしたいと考えています。 このワーカースレッドの終了のことで疑問があります。 STOPボタンを押してフラグを立てたあとにWaitForSingleObjectでスレッドの終了を待とうと思っていますが、このSTOPボタンを押したタイミングと、100件のファイルコピーが終わりワーカースレッドが自分で終了するタイミングとがかぶってしまった場合、WaitForSingleObjectで待ちに入った時点で、すでにスレッドが終了してしまっている場合が起こりうるのではないかと考えているのですが、実際にどうなのでしょうか? WaitForSingleObject実行時にすでにスレッドが破棄されていた場合、WaitForSingleObjectはどういう値を返すのでしょうか? 事前にスレッド(スレッドのハンドル)が生きているかどうかを調べる方法はあるのでしょうか? ご存知の方教えてください。 わかりづらい説明で申し訳ありません。

  • ソケット通信の受信処理について(マルチスレッド)

    今私はVisual Studio2010 C++で ソケット通信のプログラムをしているのですが、 クライアントから送ってくる文字をうまく受信できません。 接続は出来ています。 _beginthreadexでスレッドを作っています。 以下が受信の処理のスレッドになっています。 unsigned int __stdcall ThSend(void* pArg) {     CSocket_ServerDlg* pDlg = (CSocket_ServerDlg*)pArg; while(1){       char buf[256]; /* 受信するバッファ */ int buf_len; /* 受信したバイト数 */ buf_len = recv(pDlg->m_NewSoc,buf , RECVSIZE - 1, 0); if (buf_len != SOCKET_ERROR ){       buf[buf_len] = '\0'; /* 受信したバッファの後ろにNULLを付加する */       }       pDlg->m_xvEditResult += _T("Recv : ");       pDlg->m_xvEditResult += buf;       pDlg->m_xvEditResult += _T("\r\n"); } return 0; } "m_"はメンバ変数です。 以下がスレッド作成のソースになっています HANDLE hForth; unsigned int nForthID; hForth = (HANDLE)_beginthreadex(NULL, 0, ThSend , this, 0, &nForthID ); なぜ受信できないのか分からない状態です。 ではよろしくお願いします

  • C++でシングルスレッドで同期処理すべきか?

     こんばんは。 C++でプログラミングの勉強をしている者ですがシングル スレッドで同期処理をし、メイン処理からそのスレッドを実行した場合は スレッドの処理が終わるまで、そのスレッドに扱われる変数にアクセスできないという 認識で会っていますか? そもそも同期処理というのが、マルチスレッドで、同じメソッドを扱う場合、片方の処理が 終わるまでもう片方の処理は待機しているという認識で合ってますか? メイン処理からスレッドを作成し、スレッドの動きを止め、あるタイミングでスレッドの 処理を再開させる処理をメイン処理で実装することはできるでしょうか?

  • スレッドについて

    スレッドについて勉強中なのですが、簡単なスレッド作り、 スレッドの処理が終わってからメインの処理を行わせたくて 以下のようなプログラムを書いてみました。 そこで、WaitForSingleObjectを使ってスレッドが終了するのを 待ちたいのですが、WaitForSingleObjectではまってしまうようで sprintfのメッセージ(スレッドが止まってしまっている)が 表示されません。 WRITE関数の処理が終われば、、WaitForSingleObjectで処理が 戻ってくると考えているのですが…。 スレッドについてと、間違いについて教えてもらえないでしょうか? 宜しくお願いします。 main { if(!stop) {   File = CreateFile(...); g_hThead = CreateThread(NULL,0,WRITE,(LPVOID)NULL,0,NULL); g_stop = false; }else { g_stop = true; ::WaitForSingleObject(g_hThead, INFINITE); CloseHandle(File); CloseHandle(hThead ); } } void WRITE() { while(!g_stop) { WriteFile(...); } ...処理を行う sprintf("スレッドを終了します。") }

  • タイマー関数とマルチスレッドについて

    こんばんわ。 マルチスレッドプログラミングを行なっています。 コンパイラはVC++.NETでC言語を利用しwin32 apiを用いています。 スレッドを_beginthreadex関数でスレッドを2つ生成し、WaitForSingleObject,SetEvent,ResetEvent関数によるイベント同期を利用し、2スレッドの同期をはかっています。 [質問内容] 以下のように、スレッド2でWaitForSingleObject関数にてスレッド2を待機状態にし、スレッド1のSetEvent関数にて待機しているスレッド2を再開させる方法をとっています。 例えば、タイマーをスタート後に待機状態になり、スレッド2が再開後タイマーストップするとした場合、スレッド2が待機状態のときもタイマーを動き続けているのでしょうか? ・スレッド1 SetEvent(hEvent[0]); ・スレッド2 SUSPEND_INTERVAL=20 if(Num%THREAD_SUSPEND_INTERVAL==0){ timestart=timeGetTime();←タイマースタート WaitForSingleObject(hEvent[0],INFINITE); ResetEvent(hEvent[0]); timestop=timeGetTime();←タイマーストップ } よろしくお願いします。

  • マルチスレッドでCSocket::Createを呼ぶと落ちる

    VC++2008にて、サーバとクライアントPCの相互通信により、 クライアントPC側で、サーバデータを表示する エクスプローラもどきを作成しています。 サーバ側は、複数台のPCと送受信を行うため、 通信部分をマルチスレッド化しているのですが、 クライアント側は、基本的には、シングルスレッドでOKと考え、 通信部分はマルチスレッド化していませんでした。 クライアントで、ファイルアイコンをクリックしたら、 ファイルデータを受信して、ファイルをオープンし、 クローズすると、サーバへ上書きしに行く部分を、 マルチスレッドにて作成しました。 (ファイルオープンの箇所からマルチスレッド化) 問題が起こっているのは、クローズ後に、 ファイル上書きのために、CSocket派生クラスをCreateすると 落ちてしまうことです。 シングルスレッドでは、Createも正常に通るので、 マルチスレッドから、Createを呼んでることが 原因だとは思うのですが、なぜ原因となっているのか? また、どのように修正すれば良いかが分かりません。 説明が分かりづらいかもしれませんが、よろしくお願いします。

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

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

  • ファイル送受信のためのネットワークプログラミング

    現在、CSocketを用いて、クライアントPCとサーバとの メッセージの送受信プログラムを作成しています。 文字列での送受信は出来たのですが、 ファイルを送受信する方法が分かりません。 CSocketやCAsyncSocketでは、ファイルの送受信は出来ないのでしょうか?

専門家に質問してみよう