免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4883 | 回复: 4
打印 上一主题 下一主题

[C] [求助]进行多线程编程应该注意哪些问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-13 16:09 |只看该作者 |倒序浏览
参考网上牛人写的多线程扫描单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);
&nbsp;&nbsp;&nbsp;&nbsp;if (sockfd < 0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror( "nsocket ");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;/*   设为非阻塞方式   */
&nbsp;&nbsp;&nbsp;&nbsp;if ((flags = fcntl(sockfd, F_GETFL, 0))   <   0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror( "nfcntl: ");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)   <   0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror( "nfcntl: ");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;bzero(&servaddr, sizeof(servaddr));
&nbsp;&nbsp;&nbsp;&nbsp;servaddr.sin_family = AF_INET;
&nbsp;&nbsp;&nbsp;&nbsp;servaddr.sin_port = htons(nPort);

&nbsp;&nbsp;&nbsp;&nbsp;servaddr.sin_addr.s_addr = nHost;

&nbsp;&nbsp;&nbsp;&nbsp;if ((retconn = connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (EINPROGRESS != errno)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_ZERO(&wfds);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_SET(sockfd, &wfds);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;retval = select(sockfd+1, NULL, &wfds, NULL, &timeout);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (0 == retval || -1 == retval) /*   超时或者select错误   */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("out of time, retval:%dn", retval);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (FD_ISSET(sockfd, &wfds)) /*   sockfd可写   */   
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len = sizeof(error);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//perror("can't writen");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror( "nFD_ISSET: ");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (error)   /*   链接时有错误发生   */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//perror( "unkonwn");

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else /*   链接成功返回0   */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf( "  Host %s  port %d   is   opened!n ",  inet_ntoa(servaddr.sin_addr), nPort);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_nThreadNum--;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_exit(NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
}


    附:全部源码(最后测试用的,输出不是很友好 @_@)

[ 本帖最后由 godmanager 于 2009-4-15 22:33 编辑 ]

example.tar

30 KB, 下载次数: 64

端口扫描程序源码

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
2 [报告]
发表于 2009-04-13 18:54 |只看该作者
printf大法就能调试出来

论坛徽章:
0
3 [报告]
发表于 2009-04-13 19:39 |只看该作者
原帖由 xinglp 于 2009-4-13 18:54 发表
printf大法就能调试出来



   就如上面我说的,测试4,是调试之后到那里的..

   select之后
 
 一直是超时的.

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:172015亚冠之水原三星
日期:2015-06-02 16:34:202015年亚冠纪念徽章
日期:2015-10-19 18:13:37程序设计版块每日发帖之星
日期:2015-11-08 06:20:00
4 [报告]
发表于 2009-04-13 20:13 |只看该作者
不会select,帮你顶吧

论坛徽章:
0
5 [报告]
发表于 2009-04-13 21:43 |只看该作者
原帖由 xinglp 于 2009-4-13 20:13 发表
不会select,帮你顶吧



  哎....调了一个晚上了,还是没有个结果..
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP