Newsgroup: it.comp.lang.delphi
Titolo: Ping e thread

Ho un piccolo problema, sto facendo un programma che esegue
contemporaneamente dei ping (10 alla volta), su ip diversi.
Per fare questo uso TidIcmpClient delle indy e la classe TThread, in ogni
thread c'è una procedura Reply assegnata alla proprietà OnReply di
TidIcmpClient, così ogni volta che un host risponde il suo ip viene
visualizzato su un TMemo del form.
I ping vengono effettuati normalmente, ma il problema è che quando il primo
host risponde, i thread in corso (10) restituiscono tutti lo stesso ip (sul
TMemo appare quell'ip 10 volte), e poi terminano. In pratica al primo echo
reply i thread finiscono e tutte le altre risposte vengono ignorate.
Avete qualche soluzione?
Ecco il codice:
unit Unit1;    //Form principale
interface
..............................
..............................
procedure TForm1.FormCreate(Sender: TObject);
var
    thread:array[1..10] of PingThread;
    ip:array[1..10] of string;
    x:integer;
begin
    for x:=1 to 10 do
        ip[x]:='10.0.0.'+inttostr(x);   //ping da 10.0.0.1 a 10.0.0.10
    for x:=1 to 10 do begin
        thread[x]:=PingThread.Create(true);
        thread[x].host:=ip[x];
        thread[x].Resume;
    end;
end;
end.
------------------------------------------------------
unit unitThread;  //Thread
interface
uses
  Classes, idicmpclient;
type
  PingThread = class(TThread)
  private
        EchoIP:string;
        icmp:TidIcmpClient;
        ip:string;
  protected
        procedure Execute; override;
        procedure Reply(ASender: TComponent; const AReplyStatus:
TReplyStatus);
        procedure IpConnesso;
  public
        property host:string write ip;
  end;
implementation
uses unit1;
procedure PingThread.Execute;
begin
      FreeOnTerminate:=true;
      icmp:=TidIcmpClient.Create(nil);
      icmp.Host:=ip;
      icmp.ReceiveTimeout:=5000;
      icmp.OnReply:=Reply;
      icmp.Ping('',0);
end;
procedure PingThread.Reply(ASender: TComponent; const AReplyStatus:
TReplyStatus);
begin
      if areplystatus.ReplyStatusType=rsEcho then   //Host presente
        begin
              EchoIP:=areplystatus.FromIpAddress;
              synchronize(IpConnesso);
        end;
end;
procedure PingThread.IpConnesso;
begin
      form1.Memo1.Lines.Append(EchoIP);
end;
end.

 contemporaneamente dei ping (10 alla volta), su ip diversi.
Ho dato un'occhiata al tuo codice e, complice il fatto che non capisco
tantissimo di thread, non sono riuscito a trovare l'errore.
Però una soluzione pratica e veloce ci sarebbe: metti un idAntiFreeze sulla
form, e invece di creare 10 thread, crei direttamente TidIcmpClient, che se
non ricordo male, incorporano loro stessi un thread.
Questo è il codice che ho usato io, e sembra che funzioni; se poi trovi
l'errore nel tuo, dicci dov'era.
--------
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    IdAntiFreeze1: TIdAntiFreeze;
    procedure Button1Click(Sender: TObject);
  private
    procedure Reply(ASender: TComponent; const AReplyStatus: TReplyStatus);
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
    pings: Array[1..10] of TidIcmpClient;
    ip:array[1..10] of string;
    x:integer;
begin
    for x:=1 to 10 do
        ip[x]:='10.0.0.'+inttostr(x);   //ping da 10.0.0.1 a 10.0.0.10
    for x:=1 to 10 do begin
        pings[x]:=TidIcmpClient.Create(nil);
        pings[x].Host:=ip[x];
        pings[x].ReceiveTimeout:=5000;
        pings[x].OnReply:=Reply;
        pings[x].Ping;
    end;
end;
procedure TForm1.Reply(ASender: TComponent; const AReplyStatus:
TReplyStatus);
begin
  if areplystatus.ReplyStatusType=rsEcho then   //Host presente
  begin
    Memo1.Lines.Append(areplystatus.FromIpAddress);
  end;
end;
--
Jax