提高OS Windows C ++ portscanner的性能

时间:2018-11-27 18:40:01

标签: c++ performance winsock port-scanning

我用C ++编写了一个端口扫描程序,该程序将在Windows中使用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!!!\n\n");
    }
    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 %d\n", i);
        err = connect(sock, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr));

        if (err == 0)
        {
            printf("Port Open!!!\n\n\a");
            fp1 = fopen("ports.txt", "a+");
            fprintf(fp1, "Port is open: %d\n\n", i);
            closesocket(sock);
            fclose(fp1);
        }
        else
        {
            printf("Port Closed!!!\n\n");
        }
    }
    WSACleanup();
    system("ports.txt");
    }
}

1 个答案:

答案 0 :(得分:1)

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

对于要完成的操作,您需要并行运行多个connect调用。为此,您有3种选择:

  • 使用线程

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

对于少量的套接字,这是可以的,但对于大量的套接字,则不能扩展。

  • 使用无阻塞插座

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

  • 使用重叠的套接字I / O

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