改进端口扫描器的性能

Improving port scanner performance

本文关键字:性能 扫描器      更新时间:2023-10-16

所以我今天早上在c++中做了一个端口扫描仪,它似乎工作得很好,只是有一个相当烦人的问题-每当我用它来扫描网络上的IP时,它需要一个很好的10-20秒每个端口。

似乎connect()方法花了这么长时间。

现在,除了多线程,我肯定会加快进程,但不是很多,我怎么能让它更快?下面是执行扫描的代码:

for (i = 0; i < a_size(port_no); i++)
{
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    target.sin_family = AF_INET;
    target.sin_port = htons(port_no[i]);
    target.sin_addr.s_addr = inet_addr(argv[1]);
    if (connect(sock, (SOCKADDR *)&target, sizeof(target)) != SOCKET_ERROR)
        cout << "Port: " << port_no[i] << " - open" << endl;
    else
        cout << "Port: " << port_no[i] << " - closed" << endl;
    closesocket(sock);
}

如果你需要更多的,请告诉我。

哦,还有,我正在使用winsock2.h文件。是不是因为这个,它才这么慢?

呼叫connect(2)时,操作系统向对端发送SYN报文,发起三次握手。如果没有收到响应,则稍等片刻,再发送几个SYN包。如果在给定的超时时间后仍未收到响应,则操作失败,connect(2)返回错误码ETIMEODOUT

通常,如果一个对等端是up的,但在给定端口上不接受TCP连接,它将用RST数据包回复任何SYN数据包。这将导致connect(2)更快地失败(一个网络往返时间),错误为ECONNREFUSED。然而,如果对等端设置了防火墙,它就会忽略你的SYN数据包,而不会发送那些RST数据包,这将导致connect(2)需要很长时间才能失败。

因此,如果您想避免为每个端口等待超时,则需要并行执行多个连接。您可以实现这种多线程(每个线程一个同步connect(2)调用),但这不能很好地扩展,因为线程占用了相当数量的资源。

更好的方法是使用非阻塞套接字。要使套接字非阻塞,使用F_SETFL选项和O_NONBLOCK选项调用fcntl(2)。然后,connect(2)将立即返回EWOULDBLOCKEAGAIN,此时您可以使用select(2)poll(2)及其朋友同时监视大量套接字。

尝试创建一个非阻塞套接字数组,以便一次将一堆连接尝试排队。

点击这里阅读

我想出了一个适用于windows的解决方案。首先我添加了:

u_long on = 1;
timeval tv = {0, 1000};      //timeout value in microseconds
fd_set fds;
FD_ZERO(&fds);

然后我把这段代码改成这样:

for (i = 0; i < a_size(port_no); i++)
{
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    FD_SET(sock, &fds);
    ioctlsocket(sock, FIONBIO, &on);
    target.sin_family = AF_INET;
    target.sin_port = htons(port_no[i]);
    target.sin_addr.s_addr = inet_addr(argv[1]);
    connect(sock, (SOCKADDR *)&target, sizeof(target));
    err = select(sock, &fds, &fds, &fds, &tv);
    if (err != SOCKET_ERROR && err != 0)
        cout << "Port: " << port_no[i] << " - open" << endl;
    else
        cout << "Port: " << port_no[i] << " - closed" << endl;
    closesocket(sock);
}

现在似乎运行得快多了!我将做一些工作来优化它& &;清理一下,但是谢谢你所有的输入,每个人都回应了!:)