zl程序教程

您现在的位置是:首页 >  后端

当前栏目

c语言socket多线程编程限制客户端连接数

多线程客户端语言编程 限制 连接数 socket
2023-06-13 09:15:13 时间

先上一些多线程需要使用的函数定义:

复制代码代码如下:


DWORDWINAPIProcessClientRequests(LPVOIDlpParam) //新线程将会执行的函数定义
{
     return0;
}

HANDLEhandler=CreateThread(NULL,0,ProcessClientRequests,&clientsocket,0,NULL);  //这里比较简单,&clientsocket是个指针,是从主线程传入新线程的参数


WaitForMultipleObjects(MAXCLIENTS,threads,TRUE,INFINITE); //用来阻塞主线程,直到所有创建的子线程都完成任务为止,才继续执行后面的代码

for(inti=0;i<MAXCLIENTS;i++)
{
   CloseHandle(threads[i]);      //创建的每个子线程的HANDLE都会被保存在HANDLE数组中,这个函数用于关闭各个handle所对应的线程空间
}

服务器端程序

主线程代码如下:

复制代码代码如下:


#defineMAXCLIENTS3          //宏定义,最多3个客户端连接

intmain()
{
   WSADATAwsaData;
   WSAStartup(MAKEWORD(2,2),&wsaData);
   HANDLEthreads[MAXCLIENTS];

   SOCKETs=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);

   sockaddr_insockaddr;
   sockaddr.sin_family=PF_INET;
   sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
   sockaddr.sin_port=htons(9000);
   bind(s,(SOCKADDR*)&sockaddr,sizeof(SOCKADDR));

   listen(s,1);

   printf("listeningonport[%d].\n",9000);

   intexistingClientCount=0;
   while(TRUE)
   {
       SOCKADDRclientAddr;
       intsize=sizeof(SOCKADDR);

       SOCKETclientsocket;
       clientsocket=accept(s,&clientAddr,&size);
       printf("***SYS***   Newclienttouched.\n");

       if(existingClientCount<MAXCLIENTS)      //判断是否已经超出最大连接数了
       {
           threads[existingClientCount++]=CreateThread(NULL,0,ProcessClientRequests,&clientsocket,0,NULL); //启动新线程,并且将socket传入
       }
       else
       {
           char*msg="ExceededMaxincomingrequests,willrefusedthisconnect!\r\n";
           send(clientsocket,msg,strlen(msg)+sizeof(char),NULL);      //发送拒绝连接消息给客户端
           printf("***SYS***   REFUSED.\n");
           closesocket(clientsocket);                                    //释放资源
           break;
       }
   }

   printf("Maximizeclientsoccurredford%.\r\n",MAXCLIENTS);

   WaitForMultipleObjects(MAXCLIENTS,threads,TRUE,INFINITE);          //等待所有子线程,直到完成为止

   closesocket(s);
   for(inti=0;i<MAXCLIENTS;i++)
   {
       CloseHandle(threads[i]);                                          //清理线程资源
   }

   WSACleanup();

   printf("Clearedall.\r\n");

   getchar();

   exit(0);
}

子线程函数定义

复制代码代码如下:
DWORDWINAPIProcessClientRequests(LPVOIDlpParam)
{
   SOCKET*clientsocket=(SOCKET*)lpParam; //这里需要强制转换,注意:指针类型的

   char*msg="Hello,myclient.\r\n";
   send(*clientsocket,msg,strlen(msg)+sizeof(char),NULL);
   printf("***SYS***   HELLO.\n");

   while(TRUE)
   {
       charbuffer[MAXBYTE]={0};
       recv(*clientsocket,buffer,MAXBYTE,NULL);
       if(strcmp(buffer,"exit")==0)
       {
           char*msg_bye="Bye.\r\n";
           send(*clientsocket,msg_bye,strlen(msg_bye)+sizeof(char),NULL);
           break;
       }
       printf("***Client***   %s\n",buffer);
   }

   closesocket(*clientsocket);

   return0;
}