Hi!
Ich habe eine Liste mit
IP Adressen die ich der Reihe nach anpingen möchte. Die IPs gehören alle _einem_ PC. Jeder PC wird durch ein TFoo Objekt repräsentiert. Deswegen wird FAlive auch auf True gesetzt, sobald eine einzige
IP Antwort gibt.
Problem: Ich erhalte bei einer zufälligen Instanz von TFoo das PingReply Ereignis für ein anderes Objekt. Also bekommt das Objekt mit der
IP 192.168.0.2 in seiner
IP Liste auf einmal das PingErgebnis für die 192.168.0.3 (als Beispiel) und anders herum (obwohl er nicht diese
IP Adresse hat!). Das ist natürlich blöd und darf nicht sein.
Frage: Wie Pinge ich mehrere Hosts (max. 10 Stück) möglichst schnell/gleichzeitig ohne den MainThread aufzuhalten? Soll ich nur eine Instanz von TidIcmp nehmen und dann alle IPs nacheinander abarbeiten und dann den Instanzen von TFoo "per Hand" die (Nicht-)Erfolgsmeldung zukommen lassen?
Bedenke dass ein PC eine Verzögerung von 2 Sekunden haben kann, bis er antwortet. Bei 10 PCs (die angenommen alle aus sind) dauert das schon 20 Sekunden. Ich würde die Ansicht aber gerne alle 5-10 Sekunden aktualisieren lassen.
Für Antworten wie immer sehr dankbar.
Delphi-Quellcode:
procedure TFoo.Ping;
var
j: integer;
PingThread: THAL2_PC_State_Ping_Thread;
begin
FPingThreadsRunning := 0;
FintIPsReplying := 0;
for j := 0
to IP.Count - 1
do begin
inc(FPingThreadsRunning);
PingThread := Tmeinthread.Create(True);
with PingThread
do begin
Host :=
IP.Strings[j];
// IP ist eine TStringList mit den IP Adressen
Callback_Object := Self;
FreeOnTerminate := True;
Resume;
end;
end;
end;
procedure Tmeinthread.Execute;
var
idICMP: TIdIcmpClient;
begin
idICMP := TIdIcmpClient.Create(
NIL);
try
idICMP.ReceiveTimeout := 2000;
if assigned(Callback_Object)
then begin
idICMP.OnReply := Callback_Object.PingReply;
end;
idICMP.Host := Self.Host;
// <-- Self.Host ist die IP Adresse
idICMP.Ping;
finally
FreeAndNil(idICMP);
end;
end;
procedure TFoo.PingReply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
begin
if AReplyStatus.ReplyStatusType <> rsTimeOut
then begin
// if (IP.IndexOf(AReplyStatus.FromIPAddress) > -1) then begin
inc(FintIPsReplying);
FAlive := True;
// end;
end;
dec(FPingThreadsRunning);
if (FPingThreadsRunning < 1)
then begin
if (FintIPsReplying > 0)
then begin
// Hole weitere Infos
end else begin
// Der Host ist ausgeschaltet oder nicht erreichbar!
FAlive := False;
end;
end;
end;