1

所以我今天早上用 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 文件。是不是因为这个才这么慢?

4

3 回答 3

2

当您调用connect(2)时,操作系统通过向另一个对等方发送数据包来启动三次握手。SYN如果没有收到响应,它会稍等片刻,然后再发送几个SYN数据包。如果在给定超时后仍未收到响应,则操作失败,并connect(2)返回错误代码ETIMEODOUT

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

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

更好的方法是使用非阻塞套接字。要使套接字非阻塞,请fcntl(2)使用F_SETFL选项和O_NONBLOCK选项进行调用。然后,connect(2)将立即返回EWOULDBLOCKor EAGAIN,此时您可以使用select(2)orpoll(2)和朋友一起监视大量套接字。

于 2013-05-06T22:32:28.150 回答
1

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

在这里阅读

于 2013-05-06T22:13:03.593 回答
0

我想出了一个适用于 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);
}

它现在似乎运行得更快了!我会做一些工作来优化它并稍微清理一下,但是感谢您所有回复的所有输入!:)

于 2013-05-13T17:41:32.663 回答