提高了操作系统windows C++portscanner的性能



我用C++编写了一个端口扫描仪,它将在使用winsock的窗口中工作,一切都按照我想要的方式工作。只是它非常非常慢,扫描三个端口大约需要10分钟。我只是想知道是否有办法提高它的性能!

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <winsock.h>
#include <stdlib.h>
#pragma comment(lib,"WSOCK32.LIB")
int main()
{
WSADATA data;
SOCKET sock;
int err, i, startport, endport;
char ip[20];
struct sockaddr_in sock_addr;
FILE*fp1;
printf("ip: ");
scanf("n%s", ip);
printf("start port: ");
scanf("%d", &startport);
printf("end port: ");
scanf("%d", &endport);
if ((WSAStartup(MAKEWORD(2, 0), &data) != 0))
{
printf("Error: Winsock did not init!!!nn");
}
else
{
for (i = startport; i < endport; i++)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
sock_addr.sin_family = PF_INET;
sock_addr.sin_port = htons(i);
sock_addr.sin_addr.s_addr = inet_addr(ip);
printf("Checking port %dn", i);
err = connect(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr));
if (err == 0)
{
printf("Port Open!!!nna");
fp1 = fopen("ports.txt", "a+");
fprintf(fp1, "Port is open: %dnn", i);
closesocket(sock);
fclose(fp1);
}
else
{
printf("Port Closed!!!nn");
}
}
WSACleanup();
system("ports.txt");
}
}

默认情况下,套接字在阻塞模式下运行。您使用单个循环以串行方式连接到每个端口,等待一个连接完成后再尝试下一个连接。所以,性能当然会很慢。

为了实现您想要实现的目标,您需要并行运行多个连接调用。你有三个选择:

  • 使用线程

对于您创建的每个阻塞套接字,启动一个工作线程来connect()它。然后您可以创建多个套接字并一次运行它们的线程。使用WaitForMultipleObjects()(或相关函数(检测每个线程在其connect()操作完成时何时终止。

这对于少量的套接字来说是可以的,但对于大量的套接字来说则不适用。

  • 使用非阻塞套接字

对于您创建的每个套接字,使用ioctlsocket(FIONBIO)将其置于非阻塞模式。然后,您可以创建多个套接字并一次connect()它们。使用select()WSAAsyncSelect()WSAEventSelect()来检测每个connect()操作何时完成。

  • 使用重叠套接字I/O

使用启用WSA_FLAG_OVERLAPPED标志的WSASocket()创建每个套接字。然后,您可以创建多个套接字并一次创建ConnectEx(),为每个套接字指定一个单独的OVERLAPPED结构。使用WaitForMultipleObjects()+GetOverlappedResult()或I/O完成端口来检测每个ConnectEx()操作何时完成。

最新更新