プロが教える店舗&オフィスのセキュリティ対策術

winsockを使ってプログラミングしています。

1対1のチャットはできたのですが、サーバを挟んで1対多のチャットがうまくいきません。

サーバがクライアントごとにスレットを作って、acceptするたびにできるディスクリプタを配列に格納して、それを元に送信してきたクライアント以外に送るということをしたいと思っています。


説明下手ですいません。。。。

サーバ↓↓↓
・・・・・・・・・初期化は略・・・・・・・・・・・・・・・・・・・・

while(1){
Csock[i] = accept(s,(struct sockaddr *) &Saddr, &Ssize);
CreateThread(Csock[i]);  //クライアントごとにスレッドを作ってるつもり
i++;
}

/**CreateThreadで作るスレッド**********/
unsigned __stdcall recvthread(void *lpx) //lpxにはクライアントのディスクリプタを格納
{
fd_set fds, readfds;
intsock = *(int *)lpx;
intrecvSize;
charrecvbuf[256];

FD_ZERO(&readfds);
FD_SET(sock, &readfds);

while(1)
{
memcpy(&fds, &readfds, sizeof(fd_set));
memset(recvbuf, 0, sizeof(recvbuf));

select(0, &fds, NULL, NULL, NULL);

if (FD_ISSET(sock, &fds))
{
WaitForSingleObject(mutex, INFINITE);
recvSize = recv(sock, recvbuf, sizeof(recvbuf), 0);
Send(sock,(const char)recvbuf);
ReleaseMutex(mutex);

if(recvSize == 0)
{
printf("通信終了\n");
closesocket(sock);
break;
}

if(recvSize == -1)
{
printf("socket errer (recv)\n");
closesocket(sock);
break;
}
}
}
return 0;
}

void Send(int sock,char recvbuf)
{
for(int j=0;j<5;j++)
{
if(Csock[j]==sock)
continue;
send(Csock[j],(const char*)recvbuf,sizeof(recvbuf),0);
}
}

これを実行するとスレッドが無数に作成され、強制終了させられてしまいます。
初級者なのでプログラムのミスがあったら教えて下さい。
違うアイディアもあったら教えて欲しいです。見にくいと思いますがよろしくお願いします。。。。

A 回答 (2件)

気がついたことを幾つか。



1.accept()の第三引数には、第二引数に渡すバッファサイズをセットしておかないとダメです。
Ssize = sizeof( Ssize );
Csock[i] = accept( s, (struct sockaddr *)&Saddr, &Ssize );
たぶん、この値が不定値でエラーとなっているため、ブロッキングされずに、大量にスレッドが生成されているのかも?

2.一文字ずつ受信/配信より、一行ずつ処理しないと、多人数は表示がおかしくなります。
同時に入力されると、配信された文章がチャンポンになりませんか?
また、入力していた文章を、ログをみて書き直すこともあるでしょうから、
取り消しが出来るように、一行づつクライアントから送ってもらい、サーバで分散した方が、
使いやすいと思いますよ?
    • good
    • 0

while(1){


Csock[i] = accept(s,(struct sockaddr *) &Saddr, &Ssize);
CreateThread(Csock[i]);  //クライアントごとにスレッドを作ってるつもり
i++;
}

うん。これじゃあ確かにあっという間にスレッドが無数にできあがるよね。無限ループだから。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!