winsockをつかってチャットプログラムを作るには?

解決


caps  2005-07-01 03:47:15  No: 58114

はじめまして。
現在VC++.netを使用してコンソール上で動作するwinsockを利用したチャットプログラムを作成中です。
今、クライアント側がメッセージを送信して、サーバ側が受ける。そしてサーバ側がメッセージを送信して、クライアント側が受ける。というふうに交互にメッセージを送信、受信できるプログラムまではつくれました。
ここで質問なのですが、このような同期式ではなく非同期式のチャットのようなプログラムを作るにはどうすればいいのでしょうか?whileの中でrecvをして、受信するまでブロックしている状態なので、ノンブロッキングの設定をおこなえばいいのでしょうか?
もしノンブロッキングを使うとすれば、whileの中でWSAGetLastError() ==WSAEWOULDBLOCKの時にgetsをしてsendをすればいいのでしょうか?でも、これだとgetsで入力状態でとまってしまうので、チャットとはいえませんよね。
長々と書いてしまいましたが、ご教授よろしくお願いいたします。


dairygoods  2005-07-01 04:49:12  No: 58115

方法はいろいろあります。
1. タイマーを使って、一定時間間隔でノンブロッキングrecvする。
2. 受信イベントコールバックを使う。WSAAsyncSelect
3. 受信専用のスレッドを作って、ブロッキング受信する。


capx  2005-07-01 05:15:22  No: 58116

返信ありがとうございます。
自分が今作成しているサーバ側のwhileの中は
while(1){
  res=recv(c,recvbuffer,sizeof(recvbuffer),0);
  recvbuffer[res]='\0';
  printf("%s",recvbuffer);
  fgets(sendbuffer,sizeof(sendbuffer),stdin);
  res=send(c,sendbuffer,strlen(sendbuffer),0);

}
このようになっています。(この前にacceptまでは行っています)
WSAAsyncSelectを使うということは、
while(1){
      WSAAsyncSelect(c, hWnd, uMsg, lEvent);
      if(IEvent==FD_WRITE){
  fgets(sendbuffer,sizeof(sendbuffer),stdin);
  res=send(c,sendbuffer,strlen(sendbuffer),0);
  
      }
      else(IEvent==FD_READ){
     res=recv(c,recvbuffer,sizeof(recvbuffer),0);
  recvbuffer[res]='\0';
  printf("%s",recvbuffer);
      }
}このような感じでいいのでしょうか?
めちゃくちゃなプログラムですみません。
アドバイスよろしくお願いします。


dairygoods  2005-07-01 05:27:02  No: 58117

違います。

// WriteとReadを知りたい!
WSAAsyncSelect(c, hWnd, uMsg, FD_WRITE|FD_READ);

とやっておくと、イベントが発生したときに、
hWndにuMsgが届きます。


capx  2005-07-01 05:57:40  No: 58118

勉強不足ですみません。
ということは、
WSAAsyncSelect(c,hWnd,uMsg,FD_WRITE|FD_READ);
//イベントが発生したら
if(hWnd==uMsg){
相手からメッセージがとどいていたら、
recv
そうでないときは
send
}ですか?
相手からメッセージがとどいているイベントだったらなどはどういうふうに記述すればいいのでしょうか?
本当にすみません。
もしよろしければ、whileの中がどのようになるのかおしえていただけませんか?
よろしくお願いいたします。


YuO  2005-07-01 07:17:42  No: 58119

コンソールプログラムなので,スレッド+WSAAsyncEventの方が使いやすいかと。
まぁ,入力待ちの途中に出力して問題ないか,というのはわかりませんが。


dairygoods  2005-07-01 18:35:27  No: 58120

失礼、コンソールであることを見落としてました。
ウィンドウを作らなければならないので、1.2.の方法はお勧めできません。


capx  2005-07-02 02:04:36  No: 58121

ウィンドウを作らなければいけないのですか・・・。
受信専用スレッドを作成してそこでrecvするようにしたらできました。
みなさんどうもありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加