⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serv.c

📁 Introduction to the Transport Device Interface-f
💻 C
📖 第 1 页 / 共 2 页
字号:
     Serv_FreeClientList(&ServerInfo);
     closesocket(hServerSocket);

 }

/**********************************************************************
 * 
 *  Serv_ProcessSocketWait
 *
 *    Process wait for socket communications
 *
 **********************************************************************/
 BOOL Serv_ProcessSocketWait(PSERVER_INFO pServerInfo)
 {
     BOOL bProcessSocketInformation = FALSE;
     BOOL bNoDataToProcess = TRUE;
     struct timeval stTimeout;
     PCLIENT_INFO pClientInfo;
     int RetVal;

     /*
      * Loop Until Client Sends Data, Server is Terminated or Another Client Connects
      */
     while(bNoDataToProcess)
     {
           FD_ZERO(&pServerInfo->stReadFDS);
           FD_ZERO(&pServerInfo->stXcptFDS);
           FD_SET(pServerInfo->hServerSocket, &pServerInfo->stReadFDS);
           
           pServerInfo->DataSockets = 0;

           pClientInfo = pServerInfo->pClientInfoList;
    
           while(pClientInfo)
           {
              FD_SET(pClientInfo->hSocket, &pServerInfo->stReadFDS);
              pClientInfo = pClientInfo->Next;
           }
           
           stTimeout.tv_sec = 1;
           stTimeout.tv_usec = 0;
           
           RetVal = select(0, &pServerInfo->stReadFDS, NULL, &pServerInfo->stXcptFDS, &stTimeout);
    
           if(RetVal == 0 || RetVal == SOCKET_ERROR)
           {
               if(kbhit())
               {
                   switch(getch())
                   {
                       case 'q' :
                       case 'Q' :
                                 bNoDataToProcess              = FALSE;
                                 pServerInfo->bServerIsRunning = FALSE;
                                 break;
                   }
               }
           }
           else
           {
               bNoDataToProcess = FALSE;
               bProcessSocketInformation = TRUE;
               pServerInfo->DataSockets = RetVal;
           }
     }

     return bProcessSocketInformation;
 }


/**********************************************************************
 * 
 *  Serv_ProcessIncommingSockets
 *
 *    Accept new client connections
 *
 **********************************************************************/
 void Serv_ProcessIncommingSockets(PSERVER_INFO pServerInfo)
 {
   SOCKADDR_IN NewClientSockAddr = {0};
   SOCKET hNewClient;
   UINT uiLength;
   PCLIENT_INFO pClientInfo, pClientInfoWalker;

   /*
    * Check if the Server Socket has any new connecting clients
    */

   if(FD_ISSET(pServerInfo->hServerSocket, &pServerInfo->stReadFDS))
   {
        pServerInfo->DataSockets--;
        uiLength = sizeof(SOCKADDR_IN);
        
        if((hNewClient = accept(pServerInfo->hServerSocket, (struct sockaddr *)&NewClientSockAddr, &uiLength)) != INVALID_SOCKET)
        {
            /*
             * Send All Client Information to the new Client
             */
            Serv_SendNewClientBroadCast(hNewClient, pServerInfo);

            pClientInfo = Serv_CreateNewClient(hNewClient, &NewClientSockAddr);

            if(pClientInfo)
            {
                if(pServerInfo->pClientInfoList)
                {
                   pClientInfoWalker = pServerInfo->pClientInfoList;

                   while(pClientInfoWalker->Next)
                   {
                       pClientInfoWalker = pClientInfoWalker->Next;
                   }

                   pClientInfoWalker->Next = pClientInfo;
                }
                else
                {
                   pServerInfo->pClientInfoList = pClientInfo;
                }
            }
            else
            {
                Serv_DisplayErrorMsg(SERV_MEMORY_ERROR);
                closesocket(hNewClient);
            }
        }
   }
 }


/**********************************************************************
 * 
 *  Serv_CreateNewClient
 *
 *    Create a new client data structure
 *
 **********************************************************************/
 PCLIENT_INFO Serv_CreateNewClient(SOCKET hNewClientSocket, SOCKADDR_IN *pNewClientSockAddr)
 {
    PCLIENT_INFO pClientInfo;

    pClientInfo = (PCLIENT_INFO)LocalAlloc(LMEM_ZEROINIT, sizeof(CLIENT_INFO));

    if(pClientInfo)
    {
        pClientInfo->hSocket = hNewClientSocket;
        pClientInfo->SockAddr = *pNewClientSockAddr;

        printf("Connected IP = %i.%i.%i.%i\n", pClientInfo->SockAddr.sin_addr.s_addr&0xFF,
                                               pClientInfo->SockAddr.sin_addr.s_addr>>8 & 0xFF,
                                               pClientInfo->SockAddr.sin_addr.s_addr>>16 & 0xFF,
                                               pClientInfo->SockAddr.sin_addr.s_addr>>24 & 0xFF);
    }

    return pClientInfo;
 }


/**********************************************************************
 * 
 *  Serv_ProcessChatBroadcast
 *
 *    Broadcast Client Chat Messages
 *
 **********************************************************************/
 void Serv_ProcessChatBroadcast(PSERVER_INFO pServerInfo)
 {
    PCLIENT_INFO pClientInfo, pClientPrev = NULL;
    int RetVal;
    char szBuffer[1000];

    pClientInfo = pServerInfo->pClientInfoList;

    while(pServerInfo->DataSockets && pClientInfo)
    {
        if(FD_ISSET(pClientInfo->hSocket, &pServerInfo->stReadFDS))
        {
           pServerInfo->DataSockets--;
           
           /*
            * Get Incomming Data
            */
           RetVal = recv(pClientInfo->hSocket, szBuffer, sizeof(szBuffer), 0);

           /*
            * Client Error?
            */
           if(RetVal == 0 || RetVal == SOCKET_ERROR)
           {

               /*
                * If Client has a NickName, Broadcast he left the channel.
                */
               if(pClientInfo->bSetNick)
               {
                  sprintf(szBuffer, "***** %s Has Left the chat line\n", pClientInfo->Nick);
                  Serv_SendClientBroadCast(pClientInfo, pServerInfo, szBuffer);
               } 

               /*
                * Close Socket, remove client from linked list and free the memory.
                */
               closesocket(pClientInfo->hSocket);

               if(pClientPrev)
               {
                   pClientPrev->Next = pClientInfo->Next;
                   LocalFree(pClientInfo);
                   pClientInfo = pClientPrev->Next;
               }
               else
               {
                   pServerInfo->pClientInfoList = pClientInfo->Next;
                   LocalFree(pClientInfo);
                   pClientInfo = pServerInfo->pClientInfoList;
               }
               
           }
           else
           {
                
                szBuffer[RetVal] = 0;

                /*
                 * The First Packet from a client is it's nick name.
                 */
                if(!pClientInfo->bSetNick)
                {
                    

                    strcpy(pClientInfo->Nick, szBuffer);
                    sprintf(szBuffer, "*** %s has joined the chat line\n", pClientInfo->Nick);
                    
                    pClientInfo->bSetNick = TRUE;

                }

                Serv_SendClientBroadCast(pClientInfo, pServerInfo, szBuffer);

                pClientPrev = pClientInfo;
                pClientInfo = pClientInfo->Next;
           }
        }
        else
        {
            pClientPrev = pClientInfo;
            pClientInfo = pClientInfo->Next;
        }
    }
 }

/**********************************************************************
 * 
 *  Serv_FreeClientList
 *
 *    Free All Clients
 *
 **********************************************************************/
 void Serv_FreeClientList(PSERVER_INFO pServerInfo)
 {
     PCLIENT_INFO pClientInfo = pServerInfo->pClientInfoList, pNextClient;

     while(pClientInfo)
     {
         pNextClient = pClientInfo->Next;
         
         closesocket(pClientInfo->hSocket);
         LocalFree(pClientInfo);

         pClientInfo = pNextClient;
     }

     pServerInfo->pClientInfoList = NULL;
 }

/**********************************************************************
 * 
 *  Serv_SendClientBroadCast
 *
 *    Send All Connected Client Information to All but one Client
 *
 **********************************************************************/ 
 void Serv_SendClientBroadCast(PCLIENT_INFO pClientInfo, PSERVER_INFO pServerInfo, char *pszBuffer)
 {
     PCLIENT_INFO pClientRunner;
     
     pClientRunner = pServerInfo->pClientInfoList;
     
     while(pClientRunner)
     {

         if(pClientRunner != pClientInfo)
         {
             send(pClientRunner->hSocket, pszBuffer, strlen(pszBuffer) + 1, 0);
         }

         pClientRunner = pClientRunner->Next;
     }

 }

/**********************************************************************
 * 
 *  Serv_SendNewClientBroadCast
 *
 *    Send All Connected Client Information to New Client
 *
 **********************************************************************/ 
 void Serv_SendNewClientBroadCast(SOCKET hClientSocket, PSERVER_INFO pServerInfo)
 {
     char szBuffer[5000] = {0};
     PCLIENT_INFO pClientInfo;

     sprintf(szBuffer, "People Connected: ");
     pClientInfo = pServerInfo->pClientInfoList;

     while(pClientInfo)
     {
         sprintf(szBuffer, "%s %s", szBuffer, pClientInfo->Nick);
         pClientInfo = pClientInfo->Next;
     }

     sprintf(szBuffer, "%s\n", szBuffer);
     send(hClientSocket, szBuffer, strlen(szBuffer), 0);
 }



       



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -