このままだと、切断されててもソケットがどんどん浪費されていく。
接続してるソケットと使ってないソケットを区別しないと・・・・
クラスにすればいいのかな?
でもそうすると、他のクライアント達が見えなくなる、送信できなくなる
クライアントの面倒を見るクラス達を他のクラスで面倒を見てやる???
だめだ。どうなっているのやら。
自分の設計が悪いのか、2度と使われることのないクラスばっかり増産してる気がする
再利用性と汎用性がおもいっきり矛盾してる。
正しいアプローチとか、定石ってないんだろうか。
#include
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
#define MAX_BUF 1024
#define MAX_SESSION 5 //クライアント用のWindowsだと多分ライセンス的にどうだったっけ
SOCKET SockTable[MAX_SESSION]; //実際に通信で使うソケットの配列
int gID; //今何人いるか数えるカウンタ
//切断処理
void CloseConnection(int id){
int ret;
ret=1;
char buf[1024];
shutdown(SockTable[id], SD_SEND);
while(ret==0)ret=recv(SockTable[id],buf,sizeof(buf),0);
closesocket(SockTable[id]);
}
//実際にすべてのクライアントへデータを送る
int Send(SOCKET s[],char *buf,int size,int Flag){
int i;
for(i=0;i1)Send(SockTable,buf,MAX_BUF,0);
if(ret<=0)break;
}
CloseConnection(id);
ExitThread(TRUE);
}
//クライアントからの接続を受け付けて、クライアントのためのスレッドを開始
DWORD WINAPI AcceptThread(LPVOID lpvoid){
int i;
SOCKET ServSock;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
int port=(int)lpvoid;
// ソケットの作成
ServSock= socket(AF_INET,SOCK_STREAM,0);
// ソケットの設定
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
bind(ServSock, (struct sockaddr *)&addr, sizeof(addr));
printf("接続待ちです\n");
// TCPクライアントからの接続要求を待てる状態にする
listen(ServSock, 1);
// TCPクライアントからの接続要求を受け付ける
len = sizeof(client);
while(gID<MAX_SESSION){
gID++;
printf("%d番目のクライアントがきました\n",gID);
SockTable[gID]=accept(ServSock, (struct sockaddr *)&client, &len);
CreateThread(NULL , 0 , MulticastThread ,(void*)gID, 0 ,NULL);
}
}
//クライアントからの受付を開始する関数
void StartAccept(int port){
gID=0;
CreateThread(NULL , 0 , AcceptThread ,(void*)port, 0 ,NULL);
}
int main(void)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,0), &wsaData);
StartAccept(5555);
//スレッドごと巻き込んで終了するけど、正しい方法ってどうすればいいんだろう?
getch();
WSACleanup ();
return 0;
}