2015-09-26 156 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()创建一个新套接字。