各位高手,我最近遇到一socket阻塞模式与非阻塞模式的问题,小弟一直无法解决。忘各位高手给与解答。谢谢。
我的程序是一个多线程扫描端口程序。我在线程函数中设置socket为非阻塞模式,但是利用connect过程连接本机端口时却都连接不上,用阻塞模式时可以,但是执行程度太慢了,扫描10000个端口要很久(我一直都没有一次扫描完10000个端口),请各位高手帮我看看程序哪里有问题,谢谢!!
char temp[65536][99];//用于存储端号及其口状态信息
short ThreadCount=0;//当前线程数
//HWND g_hWnd = NULL;//处理消息的窗口句柄
HANDLE g_Mutex;//互斥访问量
void CScanWindow::OnBUTTONsm()
{
// TODO: Add your control notification handler code here
WSADATA wsaData;
WSAStartup(0x0002, &wsaData );
g_Mutex=CreateMutex(NULL,FALSE,NULL);
UpdateData(true);
DWORD dwThreadId;
unsigned short i=1;
do{
if(ThreadCount>200)
Sleep(10);
else if(::CreateThread(NULL,0,Scan,(LPVOID)new short(i),0,&dwThreadId)!=NULL)//传入线程参数i
{
i++;
ThreadCount++;
}
}while(i<=30000);
while(ThreadCount>0)
{
Sleep(50);
}
// char a[1]="";
for(int tempt=0;tempt<30000;tempt++)
{
m_List.AddString(temp[tempt]); //m_List为CListBox控件的变量,用于在控件中显示信息
}
for(int h=0;h<65536;h++)//置temp为空,以便下次再次存贮信息。
_strset(temp[h],NULL);
UpdateData(true);
WSACleanup();
}
DWORD WINAPI CScanWindow::Scan(LPVOID lpParam)
{
WaitForSingleObject(g_Mutex,INFINITE);
SOCKET sock;
sock=socket(AF_INET,SOCK_STREAM,0);
unsigned long J=1;
// ioctlsocket(sock,FIONBIO,&J);//设置为非阻塞模式。问题所在!!!!
short b=*(short*)lpParam;
delete lpParam;
char a[20];
itoa(b,a,10);
sockaddr_in hostaddr;
hostaddr.sin_family=AF_INET;
hostaddr.sin_port=htons((short)b);//设置端口号,由创建线程时的传入参数i定
//得到本机地址
char hostname[256];
gethostname(hostname, sizeof(hostname));
hostent* pHostent =gethostbyname(hostname);
hostent &he = *pHostent;
for (int nAdapter=0; he.h_addr_list[nAdapter]; nAdapter++)
memcpy(&hostaddr.sin_addr.s_addr,he.h_addr_list[nAdapter],he.h_length);//将主机地址传入hostaddr。准备绑定和连接
bind(sock,(PSOCKADDR)&hostaddr,sizeof(hostaddr));//绑定socket对象sock与端口。
if(connect(sock,(struct sockaddr*)&hostaddr,sizeof(hostaddr))==SOCKET_ERROR)//连接端口
{
memcpy(temp[b-1],a,strlen(a));
strcat(temp[b-1],"号端口关闭!");
ThreadCount--;
}
else
{
memcpy(temp[b-1],a,strlen(a));
strcat(temp[b-1],"号端口监听!");
ThreadCount--;
}
closesocket(sock);
ReleaseMutex(g_Mutex);
return 0;
ExitThread(0);
}