typedef struct tagThreadInfo
{
byte a1;
byte a2;
byte a3;
u_short s_ip;
u_short e_ip;
CListCtrl *pl; //列表控件指針
}ThreadInfo;
BOOL bStop; //全局變量
int i_row;void CScanIPDlg::OnScan() 
{
  //以下取得線程數
 char szThread[3];
 int ThreadNum;
 //m_tread是一個CEdit對象,
 m_thread.GetWindowText(szThread,sizeof(szThread));
 ThreadNum=10;
 if (strlen(szThread)>0) ThreadNum=atoi(szThread);//取得用戶輸入的線程數目
 if (ThreadNum<=0 || ThreadNum>30) ThreadNum=10; //對線程數進行限制(1~30) bStop=FALSE;
 i_row=0;
 ThreadInfo *m_ThreadInfo;
 for(int i=0;i<ThreadNum &&(!bStop) ;i++)
 {
   m_ThreadInfo=new ThreadInfo;
   m_ThreadInfo->pl =&m_list;
   m_ThreadInfo->hWndIp =GetDlgItem(IDC_STATIC_CURRENT)->GetSafeHwnd();
   m_ThreadInfo->a1=(BYTE)192;//a1,a2,a3是指IP地址頭如:192.180.10.xxxx
   m_ThreadInfo->a2=(BYTE)168;
   m_ThreadInfo->a3=(BYTE)10;
   //s_ip與e_ip組成掃描範圍
   m_ThreadInfo->s_ip =10;//起始,和IP頭組成192.168.10.10
   m_ThreadInfo->e_ip =200;//終止,和IP頭組成192.168.10.200   AfxBeginThread(PingThread,m_ThreadInfo,THREAD_PRIORITY_IDLE);
   Sleep(100);
  }
}線程函數:
UINT PingThread( LPVOID pParam )
{
   ThreadInfo* pThreadInfo = (ThreadInfo*)pParam;    CListCtrl *plst=(CListCtrl *)(pThreadInfo->pl);
   byte t1,t2,t3;
   t1=pThreadInfo->a1;
   t2=pThreadInfo->a2;
   t3=pThreadInfo->a3;
   
   for(int tmpIp=(pThreadInfo->s_ip);(!bStop) && tmpIp<=(pThreadInfo->e_ip);tmpIp++)
   {
     CString strIp;
     strIp.Format("%d.%d.%d.%d",t1,t2,t3,tmpIp);
     plst->InsertItem (i_row,strIp,0);
     i_row++;
   .........//掃描代碼
   }
}問:以上代碼,每個IP地址怎樣只InsertItem一次?
或者說:怎樣修改才能保證每個IP地址只掃描一次.(UP共15分,真正解決問題50分,如果分不夠,另開貼給分)

解决方案 »

  1.   

    說明:
    m_ThreadInfo->pl =&m_list; //m_list是CListCtrl控件變量
     
    下面這句不需考慮
    m_ThreadInfo->hWndIp =GetDlgItem(IDC_STATIC_CURRENT)->GetSafeHwnd();
      

  2.   

    我理解你的意思是根据用户输入的ip范围和线程数,启动若干线程,每一个线程负责一部分ip范围。你的问题在于如何平均划分这个ip范围,保证没有重复?如果是上面的意思,我的方法是:
    1. 用户输入起始地址字符串ip1, 结束地址字符串ip2,你把这两个地址用inet_addr()转换成两个32bit的ip地址形式,也就是两个长整型  addr1 和 addr2。2. 把addr1 和 addr2 按用户输入的线程数n划分,得到n组范围:
        (addr[1] addr[2]) (addr[2]+1, addr[3]),...等等,这些地址是不会重复的。把这些填入struct in_addr结构中的S_addr中,再用inet_ntoa()函数转换成字符串,填入你的结构中就可以了。
      

  3.   

    在线程中设置一个static变量,记录最后一位的ip数值,每次将其加一就可以,不会重复,简单易改。
      

  4.   


     ThreadInfo *m_ThreadInfo;
     for(int i=0;i<ThreadNum &&(!bStop) ;i++)
     {
       m_ThreadInfo=new ThreadInfo;
    你只有1个指针,但开了ThreadNum个ThreadInfo,
    不是要有ThreadNum-1个申请的内存丢了吗?
    你又没有释放
      

  5.   

    那麼換成這樣:
    ThreadInfo m_ThreadInfo;   m_ThreadInfo.pl =&m_list;
       m_ThreadInfo.a1=(BYTE)192;//a1,a2,a3是指IP地址頭如: 192.180.10.xxxx
       m_ThreadInfo.a2=(BYTE)168;
       m_ThreadInfo.a3=(BYTE)10;
       //s_ip與e_ip組成掃描範圍
       m_ThreadInfo.s_ip =10;//起始,和IP頭組成192.168.10.10
       m_ThreadInfo.e_ip =200;//終止,和IP頭組成192.168.10.200for(int i=0;i<ThreadNum &&(!bStop) ;i++)
    {
         AfxBeginThread(PingThread,&m_ThreadInfo,THREAD_PRIORITY_IDLE);
    }換成這樣後,又怎樣修改呢?
      

  6.   

    CSDN怎麼只有UP的人,沒有能夠解決問題的人?........
      

  7.   

    建议:   设置IP地址范围对话框,假设为IDC_IPFIRST,IDC_IPLAST;
       然后通过GetDlgItemText取得其输入的字符串,然后通过
       Left,Mid,Right获取相应的字段的值并将其转换为整数(atoi);
       设置相应的循环即可!
      

  8.   

    up up up up up up
      

  9.   

    可采用将IP序号散列到特定线程号的方法解决互斥问题。1。为线程增加在id 及 总线程数
    typedef struct tagThreadInfo
    {
    byte a1;
    byte a2;
    byte a3;
    u_short s_ip;
    u_short e_ip;
    CListCtrl *pl; //列表控件指針
             
             int id;
             int sum;
    }ThreadInfo;2. 创建线程时传入id 和 sum for(int i=0;i<ThreadNum &&(!bStop) ;i++)
     {
       //...
       m_ThreadInfo->id=i;
       m_ThreadInfo->sum=ThreadNum;
       //...
     }3. 相应线程搜索指定范围的ip   int begin=pThreadInfo->id+pThreadInfo->s_ip;
       int end=pThreadInfo->e_ip;
       int sum=pThreadInfo->sum;
       int i=0;
       for(; begin<end; begin+=sum)
       {
         //...
       }
      

  10.   

    修正一下:int begin=pThreadInfo->id+pThreadInfo->s_ip;
    int end=pThreadInfo->e_ip;
    int sum=pThreadInfo->sum;
    for(; begin<=end; begin+=sum)
    {
     CString strIp;
     strIp.Format("%d.%d.%d.%d",t1,t2,t3,begin);
     //..
    }
      

  11.   

    你要想达到多线程的并行运行,不能用进程互斥、同步等(当然也不能用静态变量每次加1的方法),总之每个进程之间不能有逻辑上的关系,否则就跟单线程扫描没什么区别。
       我赞同 “xuying()” 的观点,把IP范围分成N份,N=用户输入的线程数,让每个线程完成各自的IP段,这样每个线程才能高效率运行。
      

  12.   

    xuying( )的觀點還比較可行,只是不能按順序地進行掃描.