안녕 하세요???
쓰레드로 IdIcmpClient 컴포넌트를이용해서 서로다른 두곳에 핑을 돌려보는 프로그램입니다 그런데 서로 간섭현상이 발생해서요,,가끔 다운도 되고 스레드는 첨해보는거라 어렵네요
문제점이나 해결 방법을 조언해주시면 감사하겠습니다.
<main>
unit Main;
interface
uses
windows, messages, graphics, controls, forms, dialogs, stdctrls, extctrls,
SysUtils, Classes, IdIcmpClient, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,
ComCtrls;
type
TfrmPing = class(TForm)
lstReplies1: TListBox;
lstReplies2: TListBox;
Panel1: TPanel;
btnPing: TButton;
edtHost: TEdit;
Edit1: TEdit;
Button1: TButton;
StatusBar1: TStatusBar;
Answer1: TListBox;
Answer2: TListBox;
Button2: TButton;
Button3: TButton;
Label1: TLabel;
Label2: TLabel;
Button4: TButton;
procedure btnPingClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
public
procedure ThreadTerm1(Sender: TObject);
procedure ThreadTerm2(Sender: TObject);
end;
var
frmPing: TfrmPing;
implementation
{$R *.dfm}
uses
uThreadPing;
var
gThreadCount : integer;
procedure TfrmPing.btnPingClick(Sender: TObject);
begin
btnPing.Enabled := False;
lstReplies1.Items.Clear;
with TPingTest1.Create(edtHost.Text,50,1000,lstReplies1,Answer1) do
begin
OnTerminate := ThreadTerm1;
end;
Inc(gThreadCount);
statusBar1.Panels[0].Text := inttostr(gThreadCount);
end;
procedure TFrmPing.ThreadTerm1(sender: TObject);
begin
Dec(gThreadCount);
btnPing.Enabled := True;
statusBar1.Panels[0].Text := inttostr(gThreadCount);
statusBar1.Panels[1].Text := 'Thread1 Done';
end;
procedure TFrmPing.ThreadTerm2(sender: TObject);
begin
Button1.Enabled := True;
Dec(gThreadCount);
statusBar1.Panels[0].Text := inttostr(gThreadCount);
statusBar1.Panels[1].Text := 'Thread2 Done';
end;
procedure TfrmPing.Button1Click(Sender: TObject);
begin
Button1.Enabled := False;
lstReplies2.Items.Clear;
with TPingTest2.Create(edit1.Text,50,1000,lstReplies2,Answer2) do
begin
OnTerminate := ThreadTerm2;
end;
Inc(gThreadCount);
statusBar1.Panels[0].Text := inttostr(gThreadCount);
end;
procedure TfrmPing.FormCreate(Sender: TObject);
begin
gThreadCount := 0;
end;
procedure TfrmPing.Button4Click(Sender: TObject);
begin
close;
end;
end.
<sub>
unit uThreadPing;
interface
uses
Classes, IdIcmpClient, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,
SysUtils, windows, messages, graphics, controls, forms, dialogs, stdctrls, extctrls;
type
TThreadPing = class(TThread)
private
ICMP: TIdIcmpClient;
FBox1 : TListBox;
Fbox2 : TListBox;
Rp : integer;
protected
procedure Execute; override;
procedure RealPing; virtual; abstract;
procedure ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
public
constructor Create(Hst:string; Rpl: integer;TmOut: integer;Box1,Box2: TListBox);
end;
TPingTest1 = class(TThreadPing)
protected
procedure RealPing; override;
end;
TPingTest2 = class(TThreadPing)
protected
procedure RealPing; override;
end;
implementation
uses
Main;
constructor TThreadPing.Create(Hst:string; Rpl: integer;TmOut: integer;Box1,Box2: TListBox);
begin
Rp := Rpl;
FBox1 := Box1;
Fbox2 := Box2;
ICMP := TIdIcmpClient.Create(Nil);
ICMP.ReceiveTimeout := TmOut;
ICMP.Host := Hst;
FreeOnTerminate := True;
inherited Create(False);
end;
procedure TThreadPing.ICMPReply(ASender: TComponent; const ReplyStatus: TReplyStatus);
var
sTime: string;
begin
if (ReplyStatus.MsRoundTripTime = 0) then
sTime := '<1'
else
sTime := '=';
with FBox1 do
begin
Items.Add(Format('%d bytes from %s: icmp_seq=%d ttl=%d time%s%d ms',
[ReplyStatus.BytesReceived,
ReplyStatus.FromIpAddress,
ReplyStatus.SequenceId,
ReplyStatus.TimeToLive,
sTime,
ReplyStatus.MsRoundTripTime]));
end;
end;
procedure TPingTest1.RealPing;
var
i : integer;
begin
ICMP.OnReply := ICMPReply;
for i := 1 to Rp do begin
ICMP.Ping;
if Terminated then
begin
ICMP.Free;
Exit;
end;
end;
ICMP.Free;
end;
procedure TPingTest2.RealPing;
var
i : integer;
begin
ICMP.OnReply := ICMPReply;
for i := 1 to Rp do begin
ICMP.Ping;
if Terminated then
begin
ICMP.Free;
Exit;
end;
end;
ICMP.Free;
end;
procedure TThreadPing.Execute;
begin
RealPing;
end;
end.