多线程Ping的解决

来源:互联网 发布:八爪鱼淘宝采集器 编辑:程序博客网 时间:2024/04/29 13:56

多线程Ping的一种解决方式

ip地址在一个TList中,搞不定了,那位高人有做过了类似的帮帮忙,能提供源代码看看就好了
#include <vcl.h>
#pragma hdrstop

#include "ProbeThread.h"
#include "stdio.h"
#include "probe.h"
#pragma package(smart_init)

TIdIcmpClient *PingClient;
AnsiString LinkState;
AnsiString Host;
int Finished=0;
int nProbeIndex=0;
int nParseIndex=0;
//---------------------------------------------------------------------------

//   Important: Methods and properties of objects in VCL can only be
//   used in a method called using Synchronize, for example:
//
//      Synchronize(UpdateCaption);
//
//   where UpdateCaption could look like:
//
//      void __fastcall ProbeThread::UpdateCaption()
//      {
//        Form1->Caption = "Updated in a thread";
//      }
//---------------------------------------------------------------------------

__fastcall ProbeThread::ProbeThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
        FreeOnTerminate = false;
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::Execute()
{
        //---- Place thread code here ----
        PingClient=new TIdIcmpClient(NULL);
        PingClient->OnReply=ParseReply;
        while((!Terminated)&&(!Finished))
        {
                ProbeIP();
        }
        delete PingClient;             
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::ProbeIP()
{
        PingClient->ReceiveTimeout=2000;        
        PingClient->BufferSize=100;        

        Form1->pSection->Acquire();
        if(((AnsiString*)Form1->pList->Items[0])->c_str()=="")
        {
                Finished=1;
                return;
        }
        Host=((AnsiString*)Form1->pList->Items[0])->c_str();
        Form1->pList->Delete(0);
        PingClient->Host=Host;
        PingClient->Ping();
        Form1->pSection->Release();

}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::ParseReply(TComponent *ASender,
          const TReplyStatus &AReplyStatus)
{
                LinkState="连通";
                if(AReplyStatus.BytesReceived!=0)
                        LinkState="连通";
               else
                        LinkState="-----------------";

                Synchronize(Display);
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::Display()
{
      int Count=Form1->ListView1->Items->Count;
      Form1->ListView1->AddItem(PingClient->Host,NULL);
      Form1->ListView1->Items->Item[Count]->SubItems->Add(LinkState);
}

你现在有什么问题啊?

if(((AnsiString*)Form1->pList->Items[0])->c_str()=="")
这一行错误,条件永远不满足的。c_str() 返回的使一个字符串指针,用它和一个固定的字符串
直接用==相比,肯定不会成立的。如果你在List中使用了一个空白的字串作为结束符,那么这一句
应该改为:
if (*((AnsiString*)Form1->pList->Items[0])=="") 或者
if (strcmp(((AnsiString*)Form1->pList->Items[0]).c_str(),"")==0)

实际上不需要用空白的字串作为结束符的,你可以直接判断 Form1->pList->Count 是否为0 就可
以了。另外,你这种情况,用TStringList 更好一些,而没有必要使用TList。

现在的问题不是关于TList方面的,而是这个多线程如何写的问题
好像多个线程在运行的时候冲突了
不知道怎么样才能够稳定的运行!

“好像多个线程在运行的时候冲突了”具体使什么意思?你的描述有点不清不楚的。我想,还有一个主要的问题就是:ProbeIP() 这个函数执行玩之后,如果网络连接不是很快的话,ping的结果就可能还没有出来,此时你又给PingClient重新指定Host然后又再次执行ping,这样前一次ping的结果就又问题了。可以这样改(ProbeThread里增加一个变量bool IsPing):
void __fastcall ProbeThread::Execute()
{
        //---- Place thread code here ----
        PingClient=new TIdIcmpClient(NULL);
        PingClient->OnReply=ParseReply;
        IsPing = false;
        while((!Terminated)&&(!Finished))
        {
            if (IsPing)
                Sleep(1);
            else
                ProbeIP();
        }
        delete PingClient;             
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::ProbeIP()
{
        PingClient->ReceiveTimeout=2000;        
        PingClient->BufferSize=100;        

        Form1->pSection->Acquire();
        if(((AnsiString*)Form1->pList->Items[0])->c_str()=="")
        {
                Finished=1;
                return;
        }
        Host=((AnsiString*)Form1->pList->Items[0])->c_str();
        Form1->pList->Delete(0);
        PingClient->Host=Host;
        IsPing = true;
        PingClient->Ping();
        Form1->pSection->Release();

}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::ParseReply(TComponent *ASender,
    const TReplyStatus &AReplyStatus)
{
    LinkState="连通";
    if (AReplyStatus.BytesReceived!=0)
        LinkState="连通";
    else
        LinkState="-----------------";

    Synchronize(Display);

    IsPing = false;
}

刚才直接Copy你的代码,if(((AnsiString*)Form1->pList->Items[0])->c_str()=="")
这一行也忘记改正了。

已经解决

关于多线程的Ping的另外一个代码

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "ProbeThread.h"
#include "stdio.h"
#include "probe.h"
#pragma package(smart_init)


static int nProbeIndex=0;
static int nPort=50001;

__fastcall ProbeThread::ProbeThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
        FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::Execute()
{
        //---- Place thread code here ----
        TIdIcmpClient *PingClient=new TIdIcmpClient(NULL);
        PingClient->OnReply=ParseReply;
        PingClient->Port=nPort++;
        PingClient->ReceiveTimeout=2000;
        PingClient->BufferSize=100;
        while(1)
        {

                Sleep((unsigned int)100);
                Form1->pSection->Acquire();
                if(nProbeIndex>=Form1->pList->Count)
                {
                        break;
                }                              
                PingClient->Host=((AnsiString*)Form1->pList->Items[nProbeIndex])->c_str();
                nProbeIndex++;
                Form1->pSection->Release();


                PingClient->Ping();

                Form1->pTemp->Acquire();
                Form1->Memo1->Text=Form1->Memo1->Text+"/r/n";
                Form1->Memo1->Text=Form1->Memo1->Text+(AnsiString)(PingClient->Host);
                Form1->pTemp->Release();
        }

        delete PingClient;
}
//---------------------------------------------------------------------------
void __fastcall ProbeThread::ParseReply(TComponent *ASender,
          const TReplyStatus &AReplyStatus)
{
        if(AReplyStatus.BytesReceived!=0)//  &&(AReplyStatus.FromIpAddress==PingClient->Host)
        {
                Form1->pSectionOK->Acquire();
                int Count=Form1->ListView1->Items->Count;
                Form1->ListView1->AddItem(AReplyStatus.FromIpAddress,NULL);
                Form1->ListView1->Items->Item[Count]->SubItems->Add("连通");
                Form1->pSectionOK->Release();
        }
        else
        {
                Form1->pSectionErr->Acquire();
                int Count=Form1->ListView1->Items->Count;
                Form1->ListView1->AddItem(AReplyStatus.FromIpAddress,NULL);
                Form1->ListView1->Items->Item[Count]->SubItems->Add("---------------");
                Form1->pSectionErr->Release();
        }
}

/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "probe.h"
#include <stdio.h>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        ListView1->RowSelect=true;
        pList=new TList;
        pSection=new TCriticalSection();
        pTemp=new TCriticalSection();
        pSectionOK=new TCriticalSection();
        pSectionErr=new TCriticalSection();
        for(int i=0;i<200;i++)
                pThread[i]=new ProbeThread(true);
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Probe(TObject *Sender)
{
                Button1->Enabled=false;
                ReadIPAddr();
                for(int i=0;i<200;i++)
                        pThread[i]->Resume();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
        for (int i = 0; i < pList->Count; i++)
        {
                AnsiString *s= (AnsiString*)pList->Items[i];
                delete s;
        }
        delete pList;
        for(int j=0;j<200;j++)
                pThread[j]->Terminate();

        delete pSection;
        delete pSectionOK;
        delete pSectionErr;
        delete pTemp;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ReadIPAddr()
{
char ipbuf[17];
        memset(ipbuf,0,17);

        FILE *fp=fopen("c://ipaddr.dat","r");
        if(fp==NULL)
        {
                MessageBox(this,"文件打开失败!","异常",MB_OK);
                for (int i = 0; i < pList->Count; i++)
                {
                        AnsiString *s= (AnsiString*)pList->Items[i];
                        delete s;
                }
                delete pList;
                return;
        }
        while(fscanf(fp,"%[^/n]",ipbuf)!=EOF)
        {
                fgetc(fp);
                AnsiString *m=new AnsiString(ipbuf);
                pList->Add(m);
        }
        fclose(fp);
}


void __fastcall TForm1::Button2Click(TObject *Sender)
{
    for(int i=0;i<200;i++)
        pThread[i]->Suspend();
}
//---------------------------------------------------------------------------
请帮忙验证一下
我的邮箱是raw_hdlc@163.com qq:45058104 能帮忙修改一下吗?谢谢