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

このQ&Aのポイント
  • バグの原因となっているのは、マルチスレッドからCSocket派生クラスのCreateを呼び出すことです。
  • この問題を解決するためには、マルチスレッドでのクライアントの通信部分もスレッドセーフにする必要があります。
  • 修正方法は具体的には分かりませんが、クライアントの通信部分をマルチスレッド化し、適切な同期処理を行うことで解決できる可能性があります。
回答を見る
  • ベストアンサー

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

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

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

  • ベストアンサー
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.1

こちらを参照してください。 http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/csocket.html

lhouse
質問者

お礼

別スレッドを作成したのに、AfxSocketInit()を呼んでいなかったことが 原因でした。 ただし、CSocket/CAsyncSocketには根本的なバグが あるようですし、機会を見て刷新しようと思います。 ありがとうございました。

lhouse
質問者

補足

CSocket/CAsyncSocketは使うべきではないということですか。 ということは、今回の件も回避策は無いということになりますね。。。 期限の面から、通信を刷新するのは かなり厳しいので、出来れば、今回はこの点だけを 修正できることが希望だったのですが、 仕方がないのでしょうね。

関連するQ&A

  • マルチスレッドについて。

    今、大きな配列を元に処理を行うプログラムを作成しています。 シングルスレッドでも十分速度を向上するようチューニングに成功しましたが、マルチスレッド化をすればさらに速度を向上させることができるだろうと考え、先日マルチスレッドかに成功しました。 しかし・・・奇妙な現象が起こりました。 マルチスレッドで性能を引き出すには、排他制御はないほうが良いと考え、メモリは食いますがスレッドに与える入力情報(大きな配列)を2つ用意し、排他制御なしの2スレッドを実行できるようにしました。しかしやはりメモリを消費しすぎてしまうため、配列にアクセスする部分のみ排他制御を行うようクリティカルセクションを設定し入力情報を2スレッドで共有して処理を行うよう組み替えました。 結果、やはり排他制御なしの場合よりはるかにスピードダウンしてしまい、シングルスレッドより少し早い処理時間で終了してしまいました。 余りにも悔しいため、ちょっと危険な実験だとは思いましたが、入力情報を2つのスレッドで共有しているにもかかわらず、排他制御の部分、つまりクリティカルセクションを取り除いて実行してみようと考えました。予想としては同時にアクセスし衝突が起きてエラーで停止してしまうと考えましたが・・・・・・ 結果なぜかエラーなく処理をし続け、普通に終了してしまいました。 これはなぜでしょう? 偶然にも共有情報に同時にアクセスすることがなかったためでしょうか?

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

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

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

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

  • C++でマルチスレッドによるネットワークプログラムを行いたいと考えてお

    C++でマルチスレッドによるネットワークプログラムを行いたいと考えております。 質問の内容は「どちらの方が速度的に有利か?」という二択です。 Linux、C++にてサーバープログラムを作成する予定で、実装したい内容は複数人の映像チャットのようなものをP2P型ではなくサーバー-クライアント型で行います。 1部屋で10人の通信を行うとして10部屋の通信を扱いたいです。(部屋の数は変動します) そこで以下の方法のどちらが効率的かを教えていただきたいです。 方法1 外部と通信するスレッドは1つで使用するポートも一つ(100人からの接続をポーリングで対処) 部屋の中身の処理をマルチスレッド化しておき通信システムが各部屋と情報をやりとりする 方法2 部屋ごとにスレッドを作成 各部屋(スレッド)が通信機能を持ち、ポートは部屋ごとに変える 方法1、2以外に、どちらも変わらないという選択肢でも構いません。 どうぞよろしくお願い致します。

  • サーバとの通信に適したプログラム

    VisualStudio2008のMFCプロジェクトにて、 クライアントPCとサーバ間での通信を行うプログラムを作成しようとしています。 クライアントPC側で、特定の命令を送り、 それを受け取ったサーバ側で、命令に沿って、 DBのデータを送ったり、単に文字列を送ったり、 サーバ内ファイルを送り、 クライアントPCがそれを受け取るという プログラムの仕様となります。 PCとサーバでの通信プログラムは初めてで、 通信自体も詳しくないため、ネットで色々調べている 段階なのですが、どういった通信プログラミングが 適しているのかが解りません。 CAsyncSocket、CInternetsession等、 色々あるようですが、上記のような環境/仕様の場合、 何が適しているのでしょうか? 通信については勉強中につき、 漠然としすぎているのかもしれませんが、 よろしくお願いします。

  • _fcloseall

    マルチスレッドで_fcloseallを使うとほかのスレッドで開いているファイルまでクローズしてしまうのでしょうか? あるいは、別のプロセスでオープンしているファイルまでクローズしてしまうのでしょうか? 「開いているすべてのストリームを閉じます」とはどういうことなのでしょうか? よろしくお願い致します。

  • C言語でのソケット通信のclose

    C言語でソケット通信をするプログラムの見本は、大体がサーバのプログラム内でサーバとクライアントのファイルディスクリプタを、クライアントのプログラム内でクライアントのファイルディスクリプタをcloseしてから終了しています。 でも、プログラムを終了させる時にopenしているファイルディスクリプタは自動的にcloseされるのだから、わざわざ明示的にcloseする必要がないと思います。 「明示的にcloseするのがマナーだから」という理由しか、調べても出てきませんでした。 明示的に全てのファイルディスクリプタをcloseする理由をご存知の方、教えてください。

  • 受信待機

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

  • C++マルチスレッド処理について

    こんにちは 現在スレッドを作成して,マルチスレッド処理をしようとしているのですが, 全然理解できないので皆様のお力をお貸し下さい。 やりたい事は, (1) メインスレッドからスレッド1を作成。 (2) スレッド1では,ひたすらファイルなどからデータを取得させる。(読み込めなくなるまで) (3) メインスレッドでは,時々スレッド1を止めて,再度処理を続行させたい。 class Sample { public: // Sampleオブジェクト作成,同時にスレッド1を作成 Sample* create(); // スレッド1を止めて,再度動かす void process(); private: // この関数をスレッド1で処理させる // 内部では,読み込めなくなるまで無限ループ? void get(); }; スレッドに関してはイメージが湧くのですが, mutex (必要ですか?) に関しては一向に理解できません。 何を排他制御するのでしょうか。オブジェクト? 関数? 複雑ではなさそうなのですが,今までシングルスレッドの処理のみ書いていたため ピンときません。 よろしくお願い致します。

  • ソケット通信での再接続

    ソケット通信での再接続 ソケット通信でサーバ側は立ち上げたまま、 クライアント側を同じポート番号で 何度も再接続できるようにしたいと考えております。 http://blog.livedoor.jp/akf0/archives/51585502.html を参考にマルチスレッドを利用してプログラムを作成してみましたが 最初の起動に関してはうまくいくのですが、 クライアント側を一度終了してもう一度再接続すると、 バインドエラーが出ます。 いろいろ試してみたのですが、 どうしてもうまくいきません。 どうすればいいのでしょうか。 ご存じの方がいらっしゃればお答えいただきたいと思っております。 よろしくお願いいたします。 環境 OS:Windows XP 開発環境:Visual Studio 2008 Express Edition ソケット通信:winsock2 マルチスレッド:win32api

専門家に質問してみよう