我尝试使用以下代码片段扫描我的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);
}
答案 0 :(得分:0)
您正在阻塞模式下使用套接字,并在connect()
上以串行方式一次测试一个端口而没有超时。因此,扫描如此大范围的端口当然需要很长时间。您需要并行化代码,以便可以同时连接到多个端口,从而减少扫描端口范围所需的时间。
使用select()
或poll()
或等效的非阻塞套接字为connect()
提供超时(大多数平台不提供指定connect()
超时的方法在阻塞模式下,所以你受到套接字堆栈内部超时的限制。)
让多个套接字同时连接到不同的端口,无论是在单个工作线程中,还是至少在select()
/ poll()
循环中。
在任何给定时间运行有限数量的连接,以免压倒设备或网络。开始几个连接开始。当任何给定套接字连接到其当前端口时,让该线程/插槽选择下一个可用端口,如果需要,关闭+重新创建其套接字,然后重试。根据需要重复操作,直到端口范围用完为止。
每次connect()
失败而没有超时,您可以为下一个connect()
重复使用相同的套接字,您不需要close()
它。但是,如果connect()
成功,或者超时失败,则必须close()
该套接字并为下一个connect()
创建一个新套接字。