我的代码是使用WSAWaitforMultipleEvents()的UDP单服务器/多客户端应用程序。
在服务器端,有3个ReceiveThreads,每个Receive Thread都有自己的sendThread。有三个客户。所有这些都在同一台机器上运行。
ReceiveThread的代码在While(1)内。客户端还在while(1)循环中继续发送数据。
接收线程仅保持接收缓冲区并继续将缓冲区写入文本文件。
如果收到EOF或EXIT,则receivethread也应终止自身及其SendThread。
另一方面,发送线程只会继续读取另一个文本文件并继续通过套接字发送从文本文件中读取的数据。
我遇到的问题是,当我运行此代码时,CPU使用率超过100%。
是否由于服务器的所有三个线程都在While(1)中运行而所有客户端也从文本文件中读取并通过套接字在while(1)中发送数据?
我一直试图找出这种100%CPU使用率的原因,但是除了(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;
}
// ===============================================================================================================
答案 0 :(得分:2)
是的,这是因为while(1)。
默认情况下,UDP是异步的,因此任何通过recv或udp发送的while(1)循环都将以全速运行(它不会等待消息实际出现在缓冲区中)。如果性能不是您的目标,请添加
#include <time.h>
usleep(1000); // 1000 microseconds is a millisecond
这样你就可以延迟一些cpu执行周期。
实际上,UDP应该只用于线程没有时间等待IO并且可能正在进行其他计算的情况,或者如果相同的线程与用户交互并且延迟是不可接受的。