我在网上下了一个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?我的问题大概就是这样,如看不懂问题或想知道更多代码的请跟帖。多谢啦,很急~~~
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?我的问题大概就是这样,如看不懂问题或想知道更多代码的请跟帖。多谢啦,很急~~~
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);
....
}
}
假如有人能给我关于多线程的解法的话我也给分。
简单一说:
1 beginthreadex启动线程,查一个IP,然后该干什么就干什么去
2 在线程中判断是否cancel,是的话提前结束。
3 线程结束,向主线程发消息,或触发个事件,告诉它的线程儿子到寿了,快点办后事
4 主线程得到宝贝儿子一命归西,没办法,再生一个吧,于是又beginthreadex
启动线程时从list中读一个IP,然后从list中去掉这个IP,开始线程。
如果读不到IP,说明所有的IP已经运行完,程序结束。