socket异步使用SELECT等待线程一多cpu占用100%
i777 2009-05-25 06:28:58 代码其实网络上大家说的使用异步connect,然后select等待的经典代码。
我做了一个扫描网络段的程序,同时开50个线程,连接50个IP,当碰到很多IP地址主机不存在(无响应),
那么我的大部分线程select都在等待,占用cpu就会到100【等待超时8秒】。
大家看怎么解决这个问题。(我想很多人都碰到过,不知道高手怎么解决)
谢谢!!!
函数代码见下【vc++的】:
int ScanerMain::SendAndRecv(char * host,int port,char *in, char *out,int out_len)
{
char *rBuffer; /** receiving buffer */
char *sBuffer; /** receiving buffer */
rBuffer = out;
sBuffer = in;
SOCKET sock; /** used socket */
sockaddr_in sock_host;
int n_recv;
sock_host.sin_family = AF_INET;
sock_host.sin_addr.s_addr = Resol(host);
sock_host.sin_port = htons((unsigned short)port);
if(!sock_host.sin_addr.s_addr)
{
return -1;
}
if (sock = socket(AF_INET, SOCK_STREAM, 0))
{
int TimeOut=TIME_OUT_SEC*1000; //设置发送超时3秒
if( setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
//printf("thread=%d exit where setsockopt fail...\r\n",iThead);
return -1;
}
if( setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
//printf("thread=%d exit where setsockopt fail...\r\n",iThead);
return -1;
}
WriteLog ("BEGING CONNECT %s\r\n",host);
////非阻塞模式
int ul = 1;
if(ioctlsocket(sock, FIONBIO, (unsigned long*)&ul)==SOCKET_ERROR)
return -1;
connect(sock,(struct sockaddr *)&sock_host, sizeof(sock_host));
{
WriteLog ("success CONNECT %s\r\n",host);
//select 模型,即设置超时
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = TIME_OUT_SEC; //连接超时8秒
timeout.tv_usec =0;
int ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
closesocket(sock);
return 0;
}
////恢复阻塞模式
ul = 0;
if(ioctlsocket(sock, FIONBIO, (unsigned long*)&ul)==SOCKET_ERROR)
return -1;
n_recv = Request(sock, sBuffer, rBuffer, out_len);
WriteLog ("finish CONNECT %s\r\n",host);
closesocket (sock);
return n_recv;
}
/*else
{
WriteLog ("failed CONNECT %s\r\n",host);
}*/
}
return -1;
}
多谢了