C ++ Port Scanner

0

Я пытаюсь сделать сканер портов в c++, чтобы я мог получить IP-адрес от определенных устройств в моей сети, у которых был открыт определенный порт. Я выполнил тайм-аут, потому что, когда я тестирую каждый отдельный IP-адрес в своей сети, если через какое-то время я не получил ответ, он автоматически закрывает соединение.

Если я поставлю этот тайм-аут примерно на 30 секунд, он просто обнаружит все закрытые устройства, и если я ставлю гораздо большее значение, он зависает и никогда не заканчивается.

#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <string>

using namespace std;    

static bool port_is_open(string ip, int port){

    struct sockaddr_in address;  /* the libc network address data structure */
    short int sock = -1;         /* file descriptor for the network socket */
    fd_set fdset;
    struct timeval tv;

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr(ip.c_str()); /* assign the address */
    address.sin_port = htons(port);

    /* translate int2port num */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    fcntl(sock, F_SETFL, O_NONBLOCK);

    connect(sock, (struct sockaddr *)&address, sizeof(address));

    FD_ZERO(&fdset);
    FD_SET(sock, &fdset);
    tv.tv_sec = 0;             /* timeout */
    tv.tv_usec = 50;

    if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
    {
        int so_error;
        socklen_t len = sizeof so_error;

        getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);

        if (so_error == 0){
            close(sock);
            return true;
        }else{
            close(sock);
            return false;
        }
    }        
    return false;
}


int main(int argc, char **argv){    

    int i=1;        
    int port = 22;        
    while (i<255) {            
        string ip = "10.0.60.";                        
        std::string host = std::to_string(i);
        ip.append(host);            
        if (port_is_open(ip, port)){                
            printf("%s:%d is open\n", ip.c_str(), port);                
        }            
        i++;
    }           
    return 0;        
}
  • 1
    30 секунд? Тайм-аут 30 микросекунд?
  • 2
    Какой у Вас вопрос?
Показать ещё 6 комментариев
Теги:
sockets

1 ответ

2

Вы можете привязать свою логику к асинхронным вызовам и начать параллельно с разумным таймаутом (например, 10 секунд, поскольку 30% не имеет смысла в стандартных условиях). Threading ускорит вашу программу примерно в 255 раз, и она будет завершена, в худшем случае, сразу после этого таймаута:

...
#include <iostream>
#include <thread>
#include <vector>
#include <sstream>
...

void task(std::string ip, int port){
    if (port_is_open(ip, port))
        cout << ip << ":" << port << " is open\n";
}

int main(int argc, char **argv){        
    const std::string ip_prefix = "10.0.60.";
    const int port = 22;
    std::vector<std::thread *> tasks;

    for (int i=0; i<255; i++){      
        std::ostringstream ip;
        ip << ip_prefix << i;
        tasks.push_back(new std::thread(task, ip.str(), port));
    }
    for (int i=0; i<255; i++){
        tasks[i]->join();
        delete tasks[i];
    }
    return 0;
}

Вы можете скомпилировать его следующим образом: g++ -std=c++11 или g++ -std=c++0x -pthread (для более старого GCC).

  • 0
    +1 но разве вы не читали все посты с многопоточными тегами о создании столько потоков, сколько есть ядер? :))
  • 0
    @Martin James: он предназначен для машин будущего;] Если серьезно, я не видел этих тем о том, чтобы создавать столько потоков, сколько имеется ядер. Многопоточное программирование существовало в прошлом также на одноядерных процессорах и не всегда было связано с аппаратным распараллеливанием тяжелых вычислений, которое потребляет большую часть процессорной мощности для каждого ядра. Кроме того, речь идет об улучшении эффективности за счет использования времени, которое в противном случае было бы потрачено впустую процессором, в то время как ему ничего не оставалось, как ждать, например, выполнения операций с памятью, диском или сетью.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню