【发布时间】:2017-08-15 16:05:17
【问题描述】:
所以我在 Windows 上为 C 开发了一个端口扫描器,但我注意到它在某些 IP 上运行非常缓慢。这是我的代码:
DWORD WINAPI connectPortW(LPVOID lpParam)
{
HANDLE hStdout;
PMYDATA pDataArray;
WSADATA firstsock;
SOCKET s;
struct sockaddr_in sa;
int err;
char * openPorts = (char *)malloc(sizeof(char)*256);
memset(&openPorts[0], 0, strlen(openPorts));
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if(hStdout == INVALID_HANDLE_VALUE )
{
return 1;
}
pDataArray = (PMYDATA)lpParam;
strncpy((char *)&sa,"",sizeof sa);
sa.sin_family = AF_INET;
if (WSAStartup(MAKEWORD(2,0),&firstsock) != 0)
{
fprintf(stderr,"WSAStartup() failed");
exit(1);
}
sa.sin_addr.s_addr = inet_addr(pDataArray->ip);
s = socket(AF_INET, SOCK_STREAM, 0); //make net a valid socket handle
if(s < 0)
{
perror("\nSocket creation failed"); // perror function prints an error message to stderr
exit(1);
}
sa.sin_port = htons(pDataArray->port);
err = connect(s, (struct sockaddr *)&sa, sizeof sa);
//connection not accepted
if(err == SOCKET_ERROR)
{
printf("%s %-5d Winsock Error Code : %d\n", pDataArray->ip, pDataArray->port, WSAGetLastError());
strcpy("NULL", openPorts);
fflush(stdout);
}
//connection accepted
else
{
printf("%s %-5d accepted \n", pDataArray->ip, pDataArray->port);
sprintf(openPorts, "%i,", pDataArray->port);
if(shutdown(s, SD_BOTH ) == SOCKET_ERROR )
{
perror("\nshutdown");
exit(1);
}
}
closesocket(s);
fflush(stdout);
strcpy(pDataArray->openPorts, openPorts);
free(openPorts);
return 0;
}
请记住,我已经使用了线程,并且每个线程都为同一 IP 上的不同端口 (0 - 1024) 调用此函数。
那么我怎样才能加快速度呢?我一直看到人们在谈论非阻塞,这会加快速度吗?如果可以,我该如何实现。谢谢!
编辑:在上述“慢”IP 之一上从 0 到 1024 扫描需要 614 秒(10 分钟)
编辑 2:我开始尝试使用非阻塞...我这样做对吗?
ioctlsocket(s, FIONBIO, &on);
connect(s, (struct sockaddr *)&sa, sizeof sa);
FD_ZERO(&fds);
FD_SET(s, &fds);
err = select(s, &fds, &fds, &fds, &tv);
if (err != SOCKET_ERROR && err != 0)
{
sprintf(openPorts + strlen(openPorts),"%i,", pDataArray->port);
}
closesocket(s);
编辑 3:似乎这种新方法给我的结果不准确,但速度要快得多。与在同一 IP 上运行 nmap 的结果相比,我似乎获得了更多的开放端口。
【问题讨论】:
-
你知道你的瓶颈是什么吗?你分析过它吗?
-
不,我不知道它的瓶颈是什么,我该如何弄清楚它的瓶颈是什么?
-
使用异步 io 不能加快来自某些特定 ip 的回复。这根本不取决于您的代码。但是使用异步 io - 您可以使您的代码更有效并减少资源使用。 1024个线程??这是噩梦。使用异步 io,您只使用具有固定线程数的线程池(通常每个核心一个线程)
-
我一次只使用 20 个线程
-
1024 个线程是一场噩梦?根据 TM 的说法,我用来发布此消息的盒子有 1037 个现有 ATM 线程。
标签: c windows performance winapi port-scanning