我在网上下了一个Ping单个IP地址的程序,应该很多人都看过这个程序,在CSDN下载的。现在我想在此基础上添加另一个功能,就是能PING一个连续IP地址段,我需要解释的代码如下:
CPingThread::CPingThread()
{
m_dwID = 0;  
m_hThread = NULL;
m_hKillEvent =   CreateEvent(NULL,TRUE,FALSE,NULL);
m_hSignalEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
m_hThread = (HANDLE) _beginthreadex(NULL,/*Security*/
0,/*Stack size - use default*/
ThreadProc,/* Thread fn entry point*/
(void*) this,
0,// Init flag
&m_dwID);// Thread address
}
CPingThread::~CPingThread()
{
SetEvent(m_hKillEvent);
WaitForSingleObject(m_hThread,INFINITE);
}
UINT CPingThread::ThreadProc(void* lpParam)
{
CPingThread* pThis = reinterpret_cast<CPingThread*>(lpParam);
while (1)
{
HANDLE hObjects[2];
hObjects[0] = pThis->m_hKillEvent;
hObjects[1] = pThis->m_hSignalEvent; DWORD dwWait = WaitForMultipleObjects(2,hObjects,FALSE,INFINITE);
if (dwWait == WAIT_OBJECT_0)
break;
if (dwWait == WAIT_OBJECT_0 + 1)
pThis->m_ping.Ping(pThis->m_nRetries,pThis->m_strHost, pThis->m_hWnd);
}
return 0;
}
void CPingThread::StartPing(UINT nRetries,CString strHost, HWND hWnd)
{
m_nRetries = nRetries;
m_strHost = strHost;
m_hWnd = hWnd;
SetEvent(m_hSignalEvent);
}上面是一个线程代码,反正半懂半不懂。然后我在界面响应处添加如下代码:
for(i=IPbegin;i<=IPend;i++)
{
                     .......//代码省略
获得一个IP地址   .....//将IP地址转换成一个字符串
m_pingThread.StartPing(nRetries,ip,m_hWnd);//nRetries是次数
     Sleep(1800);//我的疑问就在这里,如果不要Sleep()函数的话只能得到
                                   // 最后一个IP的PING的结果,如果加Sleep()的话程序就像死机一样不动
                                //了,直到最后一下子把Ping的结果输出来,但实际我是想看一个接一个地看中间结果,
                                //就是一个线程结束了,再重新来for循环.
}
这里该怎么办才好呢?在百度看到delay()函数,SetTimer()函数,但不会用,而且介绍的太少了。还是在上面CPingThread()处做修改?我是刚学习VC的,对多线程编程不是很了解。当一个Ping结束时它会发送一个ON_MESSAGE(WM_PING_END,OnPingEnd)消息,不知道是不是可以从这个入手。是在for添加代码等到相应了ON_MESSAGE(WM_PING_END,OnPingEnd)再执行下一个IP?我的问题大概就是这样,如看不懂问题或想知道更多代码的请跟帖。多谢啦,很急~~~

解决方案 »

  1.   

    看你代码好头痛,看下WaitForMultipleObjects 和Handle之间的关系,查下msdn   不大懂你的逻辑.
      

  2.   

    这个问题我已解决了,是SetTimer()函数,代码如下:
     SetTimer(0x1001,2400,NULL);
    ...
    void CWinPingDlg::OnTimer(UINT nIDEvent) 
    {
             //PING连续IP地址段
    if(m_IPbegin<=m_IPend)
    {
        currentip[0]=(m_IPbegin&(255<<24))>>24;
        currentip[1]=(m_IPbegin&(255<<16))>>16;
        currentip[2]=(m_IPbegin&(255<<8))>>8;
             currentip[3]=m_IPbegin&255;
                 //获得字符型IP
       m_ip.Format("%d.%d.%d.%d",currentip[0],currentip[1],currentip[2],currentip[3]);
                 //开始PING
             m_pingThread.StartPing(3,m_ip,m_hWnd);
    m_IPbegin=m_IPbegin+1;  //下一个IP地址
    }
    else
    {
    KillTimer(0x1001);
    ....
    }
    }
    假如有人能给我关于多线程的解法的话我也给分。
      

  3.   

    代码是够乱的
    简单一说:
    1 beginthreadex启动线程,查一个IP,然后该干什么就干什么去
    2 在线程中判断是否cancel,是的话提前结束。
    3 线程结束,向主线程发消息,或触发个事件,告诉它的线程儿子到寿了,快点办后事
    4 主线程得到宝贝儿子一命归西,没办法,再生一个吧,于是又beginthreadex
      

  4.   

    不要用for(i=IPbegin;i <=IPend;i++) ,这样就失去用线程的意义了。也不要sleep,多线程再用sleep也没意义。把所有的IP放在一个list中,可以用CList,可以用 vector,也可以用数组,反正你要记住。
    启动线程时从list中读一个IP,然后从list中去掉这个IP,开始线程。
    如果读不到IP,说明所有的IP已经运行完,程序结束。
      

  5.   

    不大懂楼主为什么不同时开启N个线程去ping,返回结果就是了,何必要wait线程结束后再启动下一个呢?