多线程的socket程序出现cpu100%,强制终止也不行拒绝访问,
,只是在主线程开了两个转发数据的线程:
hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPDataT2C,(LPVOID)sock,0,&dwThreadID);
hThread1=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPDataC2T,(LPVOID)sock,0,&dwThreadID1);出现没有规律,用户多时cpu100%频率比较高,救命啊
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0],&fdread);
FD_SET(sock[1],&fdwrite); if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
Writelog("TCPDataC2T登记消息,用户离开");
break;
} if(ret>0)
{
//sClinet可读,client有数据要发送过来
if(FD_ISSET(sock[0],&fdread))
{
//接收sock[0]发送来的数据
iRet=recv(sock[0],szRecvFromClientBuff,BUFFERSIZE,0); if(iRet==SOCKET_ERROR)
{
Writelog("TCPDataC2T接收client数据失败");
TBWSAGetLastErrorText();
printf("\nrec from client bad\n");
Writelog("TCPDataC2T登记消息,用户离开");
break;
} else if(iRet==0)
break; Writelog("TCPDataC2T接收client数据ok");
printf("\nrecv %d bytes from sClinet.\n",iRet);
//把从client接收到的数据存添加到发往target的缓冲区
memcpy(szSendToTargetBuff+iSTTBCS,szRecvFromClientBuff,iRet);
//刷新发往target的数据缓冲区当前buff大小
iSTTBCS+=iRet;
//清空接收client数据的缓冲区
memset(szRecvFromClientBuff,0,BUFFERSIZE); } //sTarget可写,把从client接收到的数据发送到target
if(FD_ISSET(sock[1],&fdwrite))
{ //转发数据到target
iLeft=iSTTBCS;
idx=0;
while(iLeft>0)
{ iRet=send(sock[1],&szSendToTargetBuff[idx],iLeft,0);
if(iRet==SOCKET_ERROR)
{
Writelog("TCPDataC2T发送到远程机失败");
TBWSAGetLastErrorText();
printf("\nsend() to target failed:%d",GetLastError());
break;
} Writelog("TCPDataC2T发送到远程机ok");
printf("\nsend %d bytes to target",iRet);
iLeft-=iRet;
idx+=iRet;
} //清空缓冲区
memset(szSendToTargetBuff,0,BUFFERSIZE);
//重置发往target的数据缓冲区当前buff大小
iSTTBCS=0;
} }//end of select ret
Sleep(1);
}//end of data send & recv循环
,只是在主线程开了两个转发数据的线程:
hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPDataT2C,(LPVOID)sock,0,&dwThreadID);
hThread1=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TCPDataC2T,(LPVOID)sock,0,&dwThreadID1);出现没有规律,用户多时cpu100%频率比较高,救命啊
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0],&fdread);
FD_SET(sock[1],&fdwrite); if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
Writelog("TCPDataC2T登记消息,用户离开");
break;
} if(ret>0)
{
//sClinet可读,client有数据要发送过来
if(FD_ISSET(sock[0],&fdread))
{
//接收sock[0]发送来的数据
iRet=recv(sock[0],szRecvFromClientBuff,BUFFERSIZE,0); if(iRet==SOCKET_ERROR)
{
Writelog("TCPDataC2T接收client数据失败");
TBWSAGetLastErrorText();
printf("\nrec from client bad\n");
Writelog("TCPDataC2T登记消息,用户离开");
break;
} else if(iRet==0)
break; Writelog("TCPDataC2T接收client数据ok");
printf("\nrecv %d bytes from sClinet.\n",iRet);
//把从client接收到的数据存添加到发往target的缓冲区
memcpy(szSendToTargetBuff+iSTTBCS,szRecvFromClientBuff,iRet);
//刷新发往target的数据缓冲区当前buff大小
iSTTBCS+=iRet;
//清空接收client数据的缓冲区
memset(szRecvFromClientBuff,0,BUFFERSIZE); } //sTarget可写,把从client接收到的数据发送到target
if(FD_ISSET(sock[1],&fdwrite))
{ //转发数据到target
iLeft=iSTTBCS;
idx=0;
while(iLeft>0)
{ iRet=send(sock[1],&szSendToTargetBuff[idx],iLeft,0);
if(iRet==SOCKET_ERROR)
{
Writelog("TCPDataC2T发送到远程机失败");
TBWSAGetLastErrorText();
printf("\nsend() to target failed:%d",GetLastError());
break;
} Writelog("TCPDataC2T发送到远程机ok");
printf("\nsend %d bytes to target",iRet);
iLeft-=iRet;
idx+=iRet;
} //清空缓冲区
memset(szSendToTargetBuff,0,BUFFERSIZE);
//重置发往target的数据缓冲区当前buff大小
iSTTBCS=0;
} }//end of select ret
Sleep(1);
}//end of data send & recv循环
方法2:采用CEvent控制线程的开始和关闭。
在线程间也需要sleep()这样可以凑或着用
注意变量要初始化,释放完全