ページ 11

WinsockでTCP接続を用いた1対多クライアントについて

Posted: 2011年1月08日(土) 16:21
by taketoshi
こんにちは、お世話になります。
現在、C言語、winsockでTCP、VS2008stdを用いて、1対多でデータ通信が出来るソフトを練習で書いています。

必要情報を構造体に纏めて(ソケット含む)構造体の配列を定義し、複数からの接続を受け入れられたのですが
FD_CLOSEやFD_READなどのイベント情報をみても、どのクライアントからの送信かわからず
どのソケットで対応すればいいのか判らない状態になってしまいました。
1対多クライアントでプログラムを書く場合の設計から間違っているのでしょうか・・?

多クライアント接続の設計含め、打開策思いつく方、是非ご指導お願いします。

コード:

typedef struct{
	int nId;			//構造体の要素数と連動
	SOCKADDR_IN from;	//クライアント情報
	SOCKET s;			//ソケット
}DATA;

DATA MemData[MAX_MEMBER];

//winsockの通知部分を抜粋
		case FD_ACCEPT:
			if(nConnectCount == MAX_MEMBER){
				strcpy(szInfoBuff,"これ以上接続できません");
				SendMessage(hEdit[1],EM_REPLACESEL,1,(LPARAM)szInfoBuff);
				return -1;
			}
			nFromlen = sizeof(MemData->from);
			for(i = 1;i <= MAX_MEMBER;++i){
				if(MemData[i].nId == 0){
					MemData[i].nId = i;
					MemData[i].s = accept(listen_s,(sockaddr *)&MemData[i].from,&nFromlen);
					if(MemData[i].s == INVALID_SOCKET){
						strcpy(szInfoBuff,"接続ソケット生成エラー\r\n");
						SendMessage(hEdit[1],EM_REPLACESEL,1,(LPARAM)szInfoBuff);
						return false;
					}else{
						wsprintf(szOutBuff,"%s",inet_ntoa(MemData[i].from.sin_addr));
						wsprintf(szInfoBuff,"%sが接続してきました\r\n",szOutBuff);
						SendMessage(hEdit[1],EM_REPLACESEL,1,(LPARAM)szInfoBuff);
						++nConnectCount;
						return false;
					}

				}
			}
		break;
		case FD_CLOSE://どのクライアントからの遮断かを判断して対応するソケットを閉じたり、構造体を初期化する処理を書きたい
			break;
		case FD_READ://送信してきたクライアントとソケットを一致させて、そのソケットからデータを読み取りたい
			break;

Re: WinsockでTCP接続を用いた1対多クライアントについて

Posted: 2011年1月08日(土) 16:52
by softya(ソフト屋)
wParamがソケットのはずですので確認してみてください。

Re: WinsockでTCP接続を用いた1対多クライアントについて

Posted: 2011年1月08日(土) 16:54
by Ciel
少し前にwinsockで1対多の非同期通信のチャットをある程度完成させました。
まだ、未熟者ですが簡単なアドバイスをさせていただきます。

ウィンドウプロシージャのWPARAMには該当のソケットディスクリプタが格納されています。
よって、その値を利用して、クライアント側に送信なり、受信なりを行えばよいと思います。

Re: WinsockでTCP接続を用いた1対多クライアントについて

Posted: 2011年1月08日(土) 17:47
by taketoshi
お二方、ご回答ありがとうございます。早速試してみます。

これで半日位悩んでいたのでとてもすっきりしました。
また、壁にぶち当たったらよろしくお願いします。