- 论坛徽章:
- 0
|
参考网上牛人写的多线程扫描单ip多端口的扫描程序,我在这基础之上改成多线程扫描多ip的端口程序。
第一次接触多线程编程,有很多处理不是很了解,还请各为大虾指点.
测试1:
./scan 192.168.1.1 192.168.2.254 135 200
运行之后只会得到192.168.1.X这个网段的
没有192.168.2.x这个网段的
测试2:
./scan 192.168.2.1 192.168.2.254 135 200
运行之后,是可以得到192.168.2.X这个网段结果
根据测试1,测试2,我推测 只能扫描255个IP...(有点不实,只是假设)
为了验证我的推测,我又做了以下的测试,可以得到两个网段的扫描结果
测试3:
./scan 192.168.2.128 192.168.2.254 135 200
运行之后,是可以得到192.168.1.X 和192.168.2.X的结果
在程序中线程中创建都没有发生错误,只是在可能超过处理第256以后IP,都没有结果出来,调试发现,程序运行至线程函数thread_scan_host中的。。。
if (0 == retval || -1 == retval) /* 超时或者select错误 */
{
close(sockfd);
g_nThreadNum--;
printf("out of time, retval:%d\n", retval);
pthread_exit(NULL);
}
后面的IP都没有扫描结果,都为超时
不解不解呀..哪里出了问题? 线程资源没有回收?socket创建有限制?还是?
2009-4-13 21:44 问题还未解决....一步一步来,以下是自我分析..
1、线程函数的建立
计算要扫描的IP地址总量,定义为index.
以此index为for循环的上限,调用pthread_create建立线程函数。。
当创建的线程函数数量(g_nThreadNum)等于 允许最大的线程数(这里定义为200),调用sleep,直到有可用的线程数,再创建新的线程函数
2、端口扫描处理过程
建立一个非阻塞的socket,连接某主机,调用select(超时设为2秒)。
当描术符可写时,调用getsockopt,获取套接字选项,如果无错误,则表示该端口为打开的。。
看来问题应该是出在线程函数这里了,贴上来。。大家来严刑拷之
附:线程函数thread_scan_host
static void* thread_scan_host(void *phost)
{
int sockfd, flags, error,nPort, retconn, retval;
fd_set wfds;
socklen_t len;
struct sockaddr_in servaddr;
unsigned long int nHost;
pthread_detach(pthread_self());
nPort = ppport;
nHost = *(long int *)phost;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror( "nsocket ");
g_nThreadNum--;
pthread_exit(NULL);
}
/* 设为非阻塞方式 */
if ((flags = fcntl(sockfd, F_GETFL, 0)) < 0)
{
perror( "nfcntl: ");
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0)
{
perror( "nfcntl: ");
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(nPort);
servaddr.sin_addr.s_addr = nHost;
if ((retconn = connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
if (EINPROGRESS != errno)
{
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
FD_ZERO(&wfds);
FD_SET(sockfd, &wfds);
retval = select(sockfd+1, NULL, &wfds, NULL, &timeout);
if (0 == retval || -1 == retval) /* 超时或者select错误 */
{
g_nThreadNum--;
printf("out of time, retval:%dn", retval);
close(sockfd);
pthread_exit(NULL);
}
if (FD_ISSET(sockfd, &wfds)) /* sockfd可写 */
{
len = sizeof(error);
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
{
g_nThreadNum--;
//perror("can't writen");
close(sockfd);
pthread_exit(NULL);
}
}
else
{
perror( "nFD_ISSET: ");
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
if (error) /* 链接时有错误发生 */
{
//perror( "unkonwn");
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
else /* 链接成功返回0 */
{
printf( " Host %s port %d is opened!n ", inet_ntoa(servaddr.sin_addr), nPort);
g_nThreadNum--;
close(sockfd);
pthread_exit(NULL);
}
} |
附:全部源码(最后测试用的,输出不是很友好 @_@)
[ 本帖最后由 godmanager 于 2009-4-15 22:33 编辑 ] |
|