2015-09-26 155 views
-1

我試圖使用以下代碼片段掃描我的ip上打開的端口,它需要超過20分鐘才能完成,但我需要在不到一分鐘內完成任務。如果有人能給我一個想法,我很欣賞。先謝謝了。掃描打開端口

- (void)scanForOpenPorts 
{ 
    struct hostent *host; 
    int err, i, sock; 
    char hostname[100] = "192.168.1.17"; 
    struct sockaddr_in sa; 

    //Initialise the sockaddr_in structure 
    memcpy((char*)&sa , "" , sizeof sa); 
    sa.sin_family = AF_INET; 

    //direct ip address, use it 
    if(isdigit(hostname[0])) 
    { 
     printf("Doing inet_addr..."); 
     sa.sin_addr.s_addr = inet_addr(hostname); 
     printf("Done\n"); 
    } 
    //Resolve hostname to ip address 
    else if((host = gethostbyname(hostname)) != 0) 
    { 
     printf("Doing gethostbyname..."); 
     memcpy((char*)&sa.sin_addr , (char*)host->h_addr , sizeof sa.sin_addr); 
     printf("Done\n"); 
    } 
    else 
    { 
     herror(hostname); 
     exit(2); 
    } 

    //Start the port scan loop 
    printf("Starting the portscan loop : \n"); 

    NSLog(@"Start Time: %@", [NSDate date]); 

    for(i = 0; i <= 65536; i++) 
    { 
     //Fill in the port number 
     sa.sin_port = htons(i); 
     //Create a socket of type internet 
     sock = socket(AF_INET , SOCK_STREAM , 0); 

     //Check whether socket created fine or not 
     if(sock < 0) 
     { 
      perror("\nSocket"); 
      exit(1); 
     } 
     //Connect using that socket and sockaddr structure 
     err = connect(sock , (struct sockaddr*)&sa , sizeof sa); 

     //not connected 
     if(err < 0) 
     { 
      //printf("%s %-5d %s\r" , hostname , i, strerror(errno)); 
      fflush(stdout); 
     } 
     //connected 
     else 
     { 
      printf("%-5d open\n", i); 
     } 

     close(sock); 
    } 

    NSLog(@"End Time: %@", [NSDate date]); 

    printf("\r"); 
    fflush(stdout); 
} 
+1

如果這是正在運行的代碼,則它在SO上是無關緊要的。這不是代碼審查網站。那不是C代碼!不要爲非C代碼添加C標籤。 – Olaf

+1

你有C語法錯誤,像memcpy這樣的東西沒有意義;我沒有太多的信任,你甚至不明白你想要做什麼。我虛心地建議你在做這樣複雜的事情之前開始學習C語言。 –

+0

@Olaf建議它*應該*爲C ... –

回答

0

您正在使用阻塞模式插座,並與connect()沒有超時測試端口一次一個以串行方式。因此,掃描如此大範圍的端口當然需要很長時間。您需要並行化代碼,以便可以同時連接到多個端口,從而縮短掃描端口範圍所需的時間。

使用非阻塞插槽,select()poll()或相當於提供了一個超時connect()(大多數平臺不提供一種方式,阻塞方式來確定connect()超時,所以你是受套接字協議棧的內部超時) 。

有多個套接字可以同時連接到不同的端口,無論是在單獨的工作線程中,還是至少在一個循環中。

在任何給定時間運行有限數量的連接,以免壓倒設備或網絡。開始幾個連接開始。當任何給定的套接字連接到當前端口時,請讓該線程/插槽選擇下一個可用端口,如果需要關閉並重新創建其套接字,然後重試。根據需要重複,直到端口範圍已用盡。

每次connect()失敗沒有超時,你可以重複使用相同的套接字爲下一個connect(),你不需要它close()它。但是,如果connect()成功,或者由於超時而失敗,則必須將該套接字設置爲close(),併爲下一個connect()創建一個新套接字。