はじめまして。
現在VC++.netを使用してコンソール上で動作するwinsockを利用したチャットプログラムを作成中です。
今、クライアント側がメッセージを送信して、サーバ側が受ける。そしてサーバ側がメッセージを送信して、クライアント側が受ける。というふうに交互にメッセージを送信、受信できるプログラムまではつくれました。
ここで質問なのですが、このような同期式ではなく非同期式のチャットのようなプログラムを作るにはどうすればいいのでしょうか?whileの中でrecvをして、受信するまでブロックしている状態なので、ノンブロッキングの設定をおこなえばいいのでしょうか?
もしノンブロッキングを使うとすれば、whileの中でWSAGetLastError() ==WSAEWOULDBLOCKの時にgetsをしてsendをすればいいのでしょうか?でも、これだとgetsで入力状態でとまってしまうので、チャットとはいえませんよね。
長々と書いてしまいましたが、ご教授よろしくお願いいたします。
方法はいろいろあります。
1. タイマーを使って、一定時間間隔でノンブロッキングrecvする。
2. 受信イベントコールバックを使う。WSAAsyncSelect
3. 受信専用のスレッドを作って、ブロッキング受信する。
返信ありがとうございます。
自分が今作成しているサーバ側の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);
}
}このような感じでいいのでしょうか?
めちゃくちゃなプログラムですみません。
アドバイスよろしくお願いします。
違います。
// WriteとReadを知りたい!
WSAAsyncSelect(c, hWnd, uMsg, FD_WRITE|FD_READ);
とやっておくと、イベントが発生したときに、
hWndにuMsgが届きます。
勉強不足ですみません。
ということは、
WSAAsyncSelect(c,hWnd,uMsg,FD_WRITE|FD_READ);
//イベントが発生したら
if(hWnd==uMsg){
相手からメッセージがとどいていたら、
recv
そうでないときは
send
}ですか?
相手からメッセージがとどいているイベントだったらなどはどういうふうに記述すればいいのでしょうか?
本当にすみません。
もしよろしければ、whileの中がどのようになるのかおしえていただけませんか?
よろしくお願いいたします。
コンソールプログラムなので,スレッド+WSAAsyncEventの方が使いやすいかと。
まぁ,入力待ちの途中に出力して問題ないか,というのはわかりませんが。
失礼、コンソールであることを見落としてました。
ウィンドウを作らなければならないので、1.2.の方法はお勧めできません。
ウィンドウを作らなければいけないのですか・・・。
受信専用スレッドを作成してそこでrecvするようにしたらできました。
みなさんどうもありがとうございました。
ツイート | ![]() |