Gestion d'un IdIcmpClient dans un thread
Bonjour à tous
Je vous explique brièvement mon problème :
Je parcours un range d'adresse IP. Je dois faire un Ping sur chaque adresse.
Je veux gérer celà dans un Thread qui me permettra d'avoir la main sur mon programme et aussi pour que je puisse arrêter à tout moment mon application.
La fonction PingHost(Host); fonctionne très bien dans une Unit mais dans le Thread elle me pose des problème...
Mon applic ne plante pas mais en mode pas-à-pas je remarque qu'il ne passe pas la valeur du Host. Il me met : "Host = Symbol was eliminated by linker".
Voici mon code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| type
ThreadScanIP = class(TThread)
private
FProgressForm: TfrmProgressBar;
protected
procedure Execute; override;
procedure OnTerminateProcedure(Sender: TObject);
public
procedure PingHost(Host: string);
constructor Create(Suspended: Boolean);
end;
implementation
constructor ThreadScanIP.Create(Suspended: Boolean);
begin
FreeOnTerminate := True;
inherited Create(Suspended);
FProgressForm := TfrmProgressBar.Create(nil);
FProgressForm.Show;
OnTerminate := OnTerminateProcedure;
end;
procedure ThreadScanIP.Execute;
var
StartIP, EndIP, i, Count: Integer;
InAddr: TInAddr;
begin
frmMain.btnValider.Enabled := False;
Count := 0;
FProgressForm.ProgressBar.Max := frmMain.CountIP;
StartIP := ntohl(inet_addr(PChar(frmMain.IPs)));
EndIP := ntohl(inet_addr(PChar(frmMain.IPe)));
frmMain.richedit1.Enabled := False;
frmMain.richedit1.Clear;
for i := StartIP to EndIP do //Parcours le range d'adresse IP définit
begin
if (i and 255) <> 0 then
begin
InAddr.S_addr := htonl(i);
frmMain.RichEdit1.Lines.Add(inet_ntoa(InAddr)); //adresse IP parcourue
PingHost(inet_ntoa(InAddr));
FProgressForm.ProgressBar.Position := Count;
Inc(Count);
end;
end;
frmMain.richedit1.Enabled := True;
MessageBox(0, 'Traitement des adresses terminé', 'Scanning IP', MB_OK);
frmMain.btnValider.Enabled := True;
end;
procedure ThreadScanIP.OnTerminateProcedure(Sender: TObject);
begin
if Assigned(FProgressForm) then
FProgressForm.Release;
end;
procedure ThreadScanIP.PingHost(Host: string);
var
IdIcmpClient: TIdIcmpClient;
begin
IdIcmpClient := TIdIcmpClient.Create(nil);
with IdIcmpClient do
begin
try
Host := Host;
ReceiveTimeout := StrToInt(frmOptions.edtTimeOut.Text);
TTL := StrToInt(frmOptions.edtTTL.Text);
BufferSize := StrToInt(frmOptions.edtBufferSize.Text);
Ping;
case ReplyStatus.ReplyStatusType of
rsEcho:
begin
frmMain.lbLog.Items.Append(format('response from host %s in %d millisec.',
[
ReplyStatus.FromIpAddress,
ReplyStatus.MsRoundTripTime
]));
end;
rsError:
frmMain.lbLog.Items.Append('Unknown error.');
rsTimeOut:
frmMain.lbLog.Items.Append('Timed out.');
rsErrorUnreachable:
frmMain.lbLog.Items.Append(format('Host %s reports destination network unreachable.',
[ReplyStatus.FromIpAddress]));
rsErrorTTLExceeded:
frmMain.lbLog.Items.Append(format('Hope %d %s: TTL expired.',
[TTL,
ReplyStatus.FromIpAddress]));
end;
finally
Free;
end;
end;
end; |