0

我的代码是使用 WSAWaitforMultipleEvents() 的 UDP 单服务器/多客户端应用程序。

在 Server 端,有 3 个 ReceiveThread,每个 Receive Thread 都有自己的 sendThread。有三个客户。所有这些都在同一台机器上运行。

ReceiveThread 的代码在 While(1) 中。客户端还在 while(1) 循环中继续发送数据。

Receive Thread 仅继续接收缓冲区并继续将缓冲区写入文本文件。

如果收到 EOF 或 EXIT,则接收线程应终止自身及其 SendThread。

另一方面,Send Thread 只继续从另一个文本文件中读取,并继续通过套接字发送从文本文件中读取的数据。

我面临的问题是运行此代码时 CPU 使用率超过 100%。

是不是因为服务器的所有三个线程都在 While(1) 中运行,并且所有客户端也在 while(1) 中从文本文件中读取并通过套接字发送数据?

长期以来,我一直试图找出这种 100% CPU 使用率的原因,但除了 while(1) 之外,我还没有弄清楚任何事情。

编辑:

代码很长,但如果有人想看,我会添加它。

   DWORD WINAPI sendAllThreadProcedure(LPVOID param)
    {
       threadDetailStruct* myDetailStruct =  (threadDetailStruct*) (param);
       int threadNumber,portNumber;
       char *ipNumber;
       SOCKADDR_IN sendSocket = myDetailStruct->cliSock; 
       SOCKET sendSocketIdentifier = myDetailStruct->cliSockIdentifier;
       threadNumber = myDetailStruct->threadNum;


       char clientPort[32],*clientIP = inet_ntoa(sendSocket.sin_addr);
       int cliPort = ntohs(sendSocket.sin_port);
       itoa(cliPort,clientPort,10);
    //=======================================================================
       int clientSocketLength = sizeof(SOCKADDR_IN);
       char receiveBuffer[10000];
       int recv_len=0;
    //=======================================================================


       char file[32]="File.txt";
       int sendCount=0;
       FILE *fpSend;
        while(1)
        {
        if(WaitForSingleObject(terminate_thread_event[threadNumber],0) == WAIT_OBJECT_0)
           {
              ResetEvent(terminate_thread_event[threadNumber]);
              break;
           }
        if((fpSend = fopen(TEXT(fileName), "r+b")) == NULL)
        {
           //"Unable to open the File"
           continue;
        }
       else
       {
        char file_buffer[10000];
        int bytes_read=0;
        char new_buffer[1000] = "FILE",send[1000];
        if(sendto(sendSocketIdentifier, new_buffer, sizeof(new_buffer), 0, (struct sockaddr *) &sendSocket, sizeof(sendSocket))<0)
        {
         //FILE MEssage NOT SENNT!"
         continue;
        }
         else
         {
          while(fpSend!=NULL)
          {
           if(WaitForSingleObject(terminate_thread_event[threadNumber],0) == WAIT_OBJECT_0)
           {
            ResetEvent(terminate_thread_event[threadNumber]);
                closesocket(sendSocketIdentifier);
            fclose(fpSend);
            return 0;
           }
           if((bytes_read=fread(file_buffer, sizeof(char), 5, fpSend))<=0)
           {
            if(feof(fpSend))
            {
               char new_buffer[1000] = "EOF",send[1000],exit_message[12];
                   if(sendto(sendSocketIdentifier, new_buffer, sizeof(new_buffer), 0,  (struct sockaddr *) &sendSocket, sizeof(sendSocket))<0)
               {
                     //"EOF NOT SENNT!"
                     break;
               }
                   fclose(fpSend);
                   break;
            }
            else
            {
               /*Unable to copy file into buffer*/
                    fclose(fpSend);
                break;
            }
           }
          else
          {
            if(sendto(sendSocketIdentifier, file_buffer, bytes_read, 0, (struct sockaddr *) &sendSocket, sizeof(sendSocket))<0)
            {
                 //"Bytes read from File NOT SENT!"
                 fclose(fpSend);
             break;
            }
            else
            {
               sendCount = sendCount+1;
            }
          }
        }
      }
    Sleep(100);
       closesocket(sendSocketIdentifier);
       return 0;
    }

    // ====================
    // RECEIVE Thread
    DWORD WINAPI newrecvThreadProcedure(LPVOID param)
    {
       newRecvThreadDetailStruct* myDetailStruct =  (newRecvThreadDetailStruct*) (param);
    char newDetail[256], threadNumber_char[12], ipNumber[32],
    *detail = myDetailStruct>newsocketDetail;
       int portNumber,threadNumber_int = myDetailStruct->threadNum; 
       sscanf(detail,"%s %d",ipNumber,&portNumber);
       itoa(threadNumber_int,threadNumber_char,10);

       strcpy(newDetail,threadNumber_char);
       strcat(newDetail," ");
       strcat(newDetail,detail);
       struct node *cur, *newNode;

       EnterCriticalSection(&cs);
       cur =cread();
       cur->data = newDetail;
       cur->n=NULL;
       push(cur);
       newNode = pop();
       MessageBox( NULL,"PUSH DONE!","PUSH!",MB_ICONEXCLAMATION | MB_OK);
       if  (ResetEvent(data_available_event) == 0) // signal sender thread that data is available
          {
              MessageBox( NULL,"RESET Event is not Set","Failed!",MB_ICONEXCLAMATION | MB_OK);
          }
       LeaveCriticalSection(&cs);

       char file[64] = client.txt;

       //====================================================================
       // Creating New Socket Now
          WSADATA wsa; 

       //Initialise winsock//
       if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
          {
             char err[128];
             itoa(WSAGetLastError(),err,10);
             MessageBox( NULL,
                         err,
                         "WinSock Initialization FAILED",
                         MB_ICONINFORMATION);
             exit(EXIT_FAILURE);
          }

       //Create a socket//
       SOCKET newSocketIdentifier;
       SOCKADDR_IN newSocket;
       if((newSocketIdentifier = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
          { 
            // "Socket Creation Failed",
             exit(EXIT_FAILURE);
          }
       //Socket Created//

       //Prepare the sockaddr_in structure//
       newSocket.sin_family = AF_INET;
       newSocket.sin_addr.s_addr = INADDR_ANY;
       newSocket.sin_port = htons(portNumber);

       //Bind//
       if( bind(newSocketIdentifier ,(struct sockaddr *)&newSocket, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
          { 
                         //"BIND FAILED inside Thread"
          }

       //Bind Done//

       int waitRet;
       WSAEVENT hEvent = WSACreateEvent();
       WSANETWORKEVENTS events;
       WSAEventSelect(newSocketIdentifier, hEvent, FD_READ | FD_WRITE);

       SOCKADDR_IN clientSocket;
       int clientSocketLength = sizeof(SOCKADDR_IN);
       char receiveBuffer[3000]={0};
       int recv_len = 0,receiveCount = 0;

       while(1)
          {
             waitRet = WSAWaitForMultipleEvents(1, &hEvent, FALSE, INFINITE, FALSE);
             //WSAResetEvent(hEvent);
             if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
                {
                             //"FAILURE"

                   continue;
            }
             else
            {  //else event occurred starts
               if(events.lNetworkEvents & FD_READ)
                   {
                     if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
                            {
                               continue;
                            }
                         else
                            {
                               if(memcmp(receiveBuffer,"NewSocket",9) == 0)
                                  {
                                     if(sendto(newSocketIdentifier, "NewSocket ACK", sizeof("NewSocket ACK"), 0, (struct sockaddr *) &clientSocket, sizeof(clientSocket))<0)
                                        {
    //"NewSocket ACK not SENNT!",err,MB_ICONEXCLAMATION | MB_OK);
                                           continue;
                                }
                             else
                                {
                                        break;
                                }
                         }
                    }
                }
            }
          }
       threadDetailStruct threadDetail;
       threadDetail.cliSock = clientSocket;
       threadDetail.cliSockIdentifier = newSocketIdentifier;
       threadDetail.threadNum = threadNumber_int;
       AHN_glb_sendAllThreadHandle[threadNumber_int] = CreateThread( NULL,
                                                              0,
                                                              sendAllThreadProcedure,
                                                              (LPVOID)&threadDetail,
                                                              0,
                                                              &idThread[threadNumber_int]
                                                            );
       while(1)
          {
             waitRet = WSAWaitForMultipleEvents(1, &hEvent, FALSE, INFINITE, FALSE);
             //WSAResetEvent(hEvent);
             if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
                {
                              // "FAILURE"
                   continue;
            }
            else
            {  //else event occurred starts
               if(events.lNetworkEvents & FD_READ)
                 {  //check for network event starts
                         //FD_READ
                         if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
                            {
    //"after FD READ Could not Receive Data"

                                continue;
                        }

                    if(memcmp(receiveBuffer,"EXIT",4) == 0)
                        {
                                   SetEvent(terminate_thread_event[threadNumber_int]);
                        }
                    if(memcmp(receiveBuffer,"FILE",4) == 0)
                        {
                         FILE *fprecv = fopen(TEXT(file),"wb");
                        while(1)
                        {
                            waitRet = WSAWaitForMultipleEvents(1, &hEvent, FALSE, 0, FALSE);
                                  if(WSAEnumNetworkEvents(newSocketIdentifier,hEvent,&events) == SOCKET_ERROR)
                            {
                                              fclose(fprecv);
                                              break;
                            }
                            else
                            { 
                                              if(events.lNetworkEvents & FD_READ)//else event occurred starts
                              {
                                                    if((recv_len = recvfrom(newSocketIdentifier, receiveBuffer, sizeof(receiveBuffer), 0, (struct sockaddr *) &clientSocket, &clientSocketLength)) == SOCKET_ERROR)
                                                          {                                   MessageBox( NULL,"error","Data Reception Failed",MB_ICONINFORMATION);
                                                          fclose(fprecv);
                                                          exit(EXIT_FAILURE);
                                                          break;
                                          }
                                                    receiveCount = recv_len+receiveCount;
                                        if(memcmp(receiveBuffer,"EXIT",4) == 0)
                                        {
                                        SetEvent(terminate_thread_event[threadNumber_int]);
                                        fclose(fprecv);
                                        return 0;
                                        }
                                                    if(memcmp(receiveBuffer,"EOF",3) == 0)
                                                       {
                                                          fclose(fprecv);
                                                          break;
                                                       }
                                                    if(memcmp(receiveBuffer,"FILE",4) == 0)
                                                       {
                                                          fclose(fprecv);
                                                          remove(TEXT(file));
                                                          fprecv = fopen(TEXT(file),"wb");
                                                          continue;
                                                       }
                                                    **if(fwrite(receiveBuffer, 1, recv_len, fprecv)<0)
                                                       {
                                                          MessageBox( NULL,"problem while writing file","Error!",MB_ICONINFORMATION);
                                                          fclose(fprecv);
                                                          break;
                                                       }**
                                                 } //if FD_READ 
                                           }// else network event receievd ENDS
                                     }// While(1) for receiveing File Ends
                                              FILE *fp1 ;
                                              if((fp1 = fopen(TEXT(file), "rb")) == NULL)
                                                 {
                                                    MessageBox( NULL,"Unable to open the File","Error!",MB_ICONEXCLAMATION |MB_OK);
                                                    break;
                                                 }
                                              char filecmp[1000];
                                              strcpy(filecmp,"Client");
                                              strcat(filecmp,threadNumber_char);
                                              strcat(filecmp,"Original");
                                              strcat(filecmp,".txt");
                                              FILE *fp2 ;
                                              if((fp2 = fopen(TEXT(filecmp), "rb")) == NULL)
                                                 {
                                                     MessageBox( NULL,"Unable to open the Original File","Error!",MB_ICONEXCLAMATION | MB_OK);
                                                     break;
                                                 }
                                              int ch1  =  getc( fp1 ) ;
                                              int ch2  =  getc( fp2 ) ;
                                              while( (ch1!=EOF) && (ch2!=EOF) && (ch1 == ch2))
                                                 {
                                                    ch1 = getc(fp1);
                                                    ch2 = getc(fp2) ;
                                                 }
                                              char display[3000];
                                              strcpy(display,file);
                                              strcat(display," Received and ");
                                              strcat(display,filecmp);
                                              int idx=GetWindowTextLength(AHN_glb_resultWindowHandle);
                                              SendMessage(AHN_glb_resultWindowHandle,EM_SETSEL,idx,idx);
                                              SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)"\r\n");
                                              if (ch1 !=  ch2)
                                                 {
                                                    SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)"\r\n");
                                                    SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)" ");
                                                    SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)TEXT(display));
                                                    SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)" are Not Identical");
                                                 }
                                              else if (ch1 == ch2)
                                                 {
                                                     SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)"\r\n");
                                                     SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)" ");
                                                     SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)TEXT(display));
                                                     SendMessage(AHN_glb_resultWindowHandle,EM_REPLACESEL,0,(LPARAM)" are Identical");
                                                 }

    fclose ( fp1 );
    fclose ( fp2 );

                                } //if memecmp == FILE ENDS
                    } //if FD_READ ENDS
                }// else if event occurred ENDS
        }//while(1) ENDS
       return 0;
    }
    // ===============================================================================================================
4

1 回答 1

2

是的,这是因为 while(1)。

默认情况下,UDP 是异步的,因此任何通过 recv 或通过 udp 发送的 while(1) 循环都将全速运行(它不会等待消息实际出现在缓冲区中)。如果性能不是您的目标,请添加

#include <time.h>    
usleep(1000); // 1000 microseconds is a millisecond 

这样您就可以延迟一些 cpu 执行周期。

实际上,UDP 应该只在线程没有时间等待 IO 并且它可能正在执行其他计算的情况下使用,或者如果同一线程与用户交互并且延迟是不可接受的。

于 2013-06-11T12:28:29.440 回答