- 締切済み
マルチスレッドチャットプログラム作成方法
マルチスレッドでチャットプログラムが組みたいです。 winsockを用いてVC++2010EEで組んでいます。 selectでのC/S型チャットプログラムは組めます。 マルチスレッドプログラムに関しては「猫でもわかるプログラミング」C言語編第1部第99章以降を参考にしました。 このサイトでのプログラムは分かるのですが、いざ自分のチャットプログラムに実装しようとするとどうすればいいのか分からなくなります。 やりたいこと(こうすればいいのだろうと思っていること)は winsockの設定 while(1) { ----SockBuf = accept(略); --------if( SockBuf != INVALID_SOCKET) --------{ ------------MaxClient++; ------------Sock.push_back(SockBuf); --------} ----thread()をSock[0]~Sock[MaxClient-1]ごとにスレッドで動かしたい。 ----その他の処理 } unsigned __stdcall thread() { ----recv(略) ----その他の処理 } どのようにしたらいいのか分からないので教えてください。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- Wr5
- ベストアンサー率53% (2173/4061)
ちょいと適当過ぎましたかねぇ…。 #2の疑似コードだと、 ・全クライアントへのsend()が完了するまで、共有メモリを保護しないとならない。 ・接続断の場合が考慮されていない。 などなど……。 まぁ、そこらへんはよろしく処理して下さい。ということで……。 考え方の1つの参考にでもして下さいな。 プロトコル次第っていうのもありますが。 Windowsであるかは不明ですが、IRCサーバのソースとかが参考に……なるかなぁ。 他のサーバとの同期処理とかは不要でしょうけどねえ。
- Wr5
- ベストアンサー率53% (2173/4061)
>出来たらforループを使わずに、 どこからforループ出てきたのかが…… マルチスレッドとselect()だと http://x68000.q-e-d.net/~68user/net/c-echo-2.html とか参考になります…かねぇ。 クライアント側は現状で出来ているという「C/S型チャットプログラム」のままとして、 サーバ側では… accept()で作成されたソケットを専用のスレッドに渡して処理…でしょう。 発言内容を他のクライアントにも送信する為の「共有メモリ」(同一プロセスですからサイズ決めうちでもかまわんでしょう) 発言内容に設定完了を通知する「イベント」、 共有メモリのアクセス制御の為の「同期オブジェクト」などを用意して…… while(!EndFlag) { FD_ZERO() FD_SET() select() //上記のFD_SETしたものを第1引数(受信確認)に、200ms程度でタイムアウトするように設定 if(FD_ISSET()) { // 受信データ処理 // 受信内容に応じてもろろ処理 } // 受信内容が発言内容ならば、同期オブジェクトで書き込み権限取得して、共有メモリに書き込み、イベントを設定する。 // 同期オブジェクトで権限取得出来なかったら、次のループの時に際取得。 // WaitForSingleObject()で発言内容のイベントが立ったら、send()でクライアントに送信する。 } ってな感じのループで処理できるんじゃないでしょうかね? # 発言内容設定完了イベントを誰がクリアするのか…とか、その辺りはもう少し考慮が必要でしょうけどね…。 # エラー処理とかそういうところは入っていませんが…よろしく処理して下さい。 >Sock[0]、Sock[3]、Sock[7] >から受信があったとしたら >3つのスレッド(プロセス?)が起動して処理が終わったら消え・・・・・ >というようなことがしたいのですが、 クライアントが切断するまではスレッドは生かしたままでいいと思いますけどね。 1発言(?)ごとにスレッド起こすのはムダでしょう。
- Wr5
- ベストアンサー率53% (2173/4061)
>selectでのC/S型チャットプログラムは組めます。 であれば…… 作成したスレッド中でしょりすればよいかと。 クライアント側はあくまでもサーバと1対1の通信のみにして、サーバ側で各クライアントからの発言を他のクライアントに送る。 ということになるでしょうね。 サーバ側をやったことはありませんので細かいところまでは不明ですが。 私がやったことあるのはクライアント側で、複数のPOPサーバとおしゃべりしてみましょう…って程度ですので。 # select()じゃなくてWSAAsyncSelect()でメッセージ処理してましたけど。 # 同期処理はちょっとハマりましたけどね。設計がイマイチだからですが。 英語ですが下記ページとか見てみてはどうですかね? http://msdn.microsoft.com/en-us/library/windows/desktop/ms738545%28v=vs.85%29.aspx Complete Winsock Server Codeで… // Accept a client socket で接続受けた後辺りから、 // cleanup のclosesocket()までがスレッドで処理する範囲になるでしょう。 送受信はselect()で面倒見る必要がありますし、 このサンプルでは早々にlisten()のソケット閉じていたりはしますが。 # SOMAXCONNのコネクション受け付けるようにしているわりには接続1個で閉じてる。
補足
>作成したスレッド中でしょりすればよいかと。 済みません。もうちょっと詳しくお願いします。 出来たらforループを使わずに、 Sock[0]、Sock[3]、Sock[7] から受信があったとしたら 3つのスレッド(プロセス?)が起動して処理が終わったら消え・・・・・ というようなことがしたいのですが、