안녕하세요.!! 델초보입니다..
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;
=====================================================================
꼭 좀 봐주시기 바랍니다..ㅜ.ㅜ
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;