Q&A

  • icmp에 thread를 이용해서 만들었거든요 일주일째 헤매고 있네요
안녕 하세요???
쓰레드로  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.

0  COMMENTS