Q&A

  • ICMP 컴포넌트를 이용해 Ping 할때..질문있습니다.
안녕하세요.!! 델초보입니다..

Indy에 ICMP 컴포넌트를 이용해..델파이 데모 폴더에 있는 PingGUI 예제를

이용해..조금 다르게..해봤습니다..근데..좀 이상한게 있어서요..

IPAddress를 ListView에 등록해서 등록된 IP만큼 Count 수 많큼 해당 IP

에 Ping을 해서 출력하는 내용입니다.

정상적으로..나온값은 아래와 같이 (아래는 예제 출력물)
=====================================================================
from 211.110.1.1  72bytes  icmp_seq = 0  ttl = 246  time = 20 ms
from 211.110.1.2  72bytes  icmp_seq = 1  ttl = 246  time < 10 ms
..
.
=====================================================================

ListView에 업데이트 시킨 출력물
=====================================================================
from 211.110.1.1  72bytes  icmp_seq = 1  ttl = 246  time < 10 ms
from 211.110.1.2  72bytes  icmp_seq = 1  ttl = 246  time < 10 ms
..
.
=====================================================================
위 출력물 2개 에서 차이를 느끼셨겠지만...

해당 IP 맨 마지막 꺼를 등록된 IP 만큼 출력하더라구요..

그래서..질문을 드리고자 합니다..소스가 어디에서 이상이 있는지...요

=====================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ListItem : TListItem;
begin
    ListItem := ListView1.Items.Add;
    ListItem.Caption := Edit1.Text;
    ListItem.SubItems.Add(Edit2.Text);
    ListItem.SubItems.Add('');
    ListItem.SubItems.Add('');
    ListItem.SubItems.Add('');
    ListItem.SubItems.Add('');
    ListItem.SubItems.Add('');
end;

procedure TForm1.Button4Click(Sender: TObject);
var
   I : Integer;
begin
    for I := 0 to Form1.ListView1.Items.Count-1 do
    begin
     Form1.ICMP.Host := ListView1.Items[i].Caption;
     Form1.ICMP.Ping;
     Application.ProcessMessages;
     end;
end;

procedure TForm1.ICMPReply(ASender: TComponent;
  const AReplyStatus: TReplyStatus);
var
  i : Integer;
  sTime: string;
begin

   if (AReplyStatus.MsRoundTripTime = 0) then
     sTime := '<1'
   else
     sTime := '=';

    for i:= 0 to ListView1.Items.Count-1 do
    begin
        with ListView1.Items do      --> 여기서 이상한거 같은데..머가잘못된건지..
        begin                            여기 for문에서 ListView count수 만큼 똑같은게 돌더라구요..

            Item[i].Caption := AReplyStatus.FromIpAddress;
            Item[i].SubItems.Strings[0] := ListView1.Items.Item[i].SubItems.Strings[0];
            Item[i].SubItems.Strings[1] := IntToStr(AReplyStatus.BytesReceived) + ' bytes';
            Item[i].SubItems.Strings[2] := 'icmp_seq = ' + IntToStr(AReplyStatus.SequenceId);
            Item[i].SubItems.Strings[3] := 'ttl = ' + IntToStr(AReplyStatus.TimeToLive);
//            Item[i].SubItems.Strings[4] := 'time ' + sTime + 'ms';;
            Item[i].SubItems.Strings[5] := IntToStr(AReplyStatus.MsRoundTripTime);
        end;
    end;
end;

=====================================================================
꼭 좀 봐주시기 바랍니다..ㅜ.ㅜ
2  COMMENTS
  • Profile
    윤수아 2002.09.05 02:41
    for i:= 0 to ListView1.Items.Count-1 do
        begin
            with ListView1.Items do      --> 여기서 이상한거 같은데..머가잘못된건지..
            begin                            여기 for문에서 ListView count수 만큼 똑같은게 돌더라구요..

                Item[i].Caption := AReplyStatus.FromIpAddress;
                Item[i].SubItems.Strings[0] := ListView1.Items.Item[i].SubItems.Strings[0];
                Item[i].SubItems.Strings[1] := IntToStr(AReplyStatus.BytesReceived) + ' bytes';
                Item[i].SubItems.Strings[2] := 'icmp_seq = ' + IntToStr(AReplyStatus.SequenceId);
                Item[i].SubItems.Strings[3] := 'ttl = ' + IntToStr(AReplyStatus.TimeToLive);
    //            Item[i].SubItems.Strings[4] := 'time ' + sTime + 'ms';;
                Item[i].SubItems.Strings[5] := IntToStr(AReplyStatus.MsRoundTripTime);
            end;
        end;

    이부분에서 for i:= 0 to ListView1.Items.Count-1 do 이 구문때문에
    ListView 전체가 갱신되는 겁니다.
    현재 응답온 것만 갱신해야 되는데....
    ListView1의 갯수만큼 돌면서 다 같은 값을 채워 놓게 되어 있쟎아요...
    그러니까 마지막의 값들이 다들어가게 되죠...음....


    <<임의로 ListView의 서브아이템 갯수를 하나 줄였습니다...Subitems[0]은 당최 몰 하는건지 몰라서...암튼 PingIndex 를 하나 선언해서 하심이...좋을듯하네요>>
    procedure TForm1.Button1Click(Sender: TObject);
    var
       I : Integer;
    begin
      if ListView1.Items.count <> 0 then
      begin
        PingIndex := 0; //전역으로 선언 Private에다가
        Icmp.Host := ListView1.Items[PingIndex].Caption;
        Icmp.Ping;
      end;
    end;

    procedure TForm1.IcmpReply(ASender: TComponent;
      const AReplyStatus: TReplyStatus);
    var
      sTime: string;
    begin
      if (AReplyStatus.MsRoundTripTime = 0) then sTime := '<1'
      else                                       sTime := '=';
      with ListView1.Items do
      begin
        Item[PingIndex].Caption := AReplyStatus.FromIpAddress;
        Item[PingIndex].SubItems.Strings[0] := IntToStr(AReplyStatus.BytesReceived) + ' bytes';
        Item[PingIndex].SubItems.Strings[1] := 'icmp_seq = ' + IntToStr(AReplyStatus.SequenceId);
        Item[PingIndex].SubItems.Strings[2] := 'ttl = ' + IntToStr(AReplyStatus.TimeToLive);
        Item[PingIndex].SubItems.Strings[3] := 'time ' + sTime + 'ms';;
        Item[PingIndex].SubItems.Strings[4] := IntToStr(AReplyStatus.MsRoundTripTime);
      end;
      Inc(PingIndex);
      if PingIndex > Listview1.Items.Count - 1 then exit;
      IcmpClient1.Host := ListView1.Items[PingIndex].Caption;
      IcmpClient1.Ping;
    end;
  • Profile
    최수림 2002.09.06 21:28
    감사합니다..!! 정말..감사합니다...!!

    조금 인사가 늦었습니다..^^

    좋은 하루 되세요..!!