Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Потоки и пинг [D7, WinXP]


Страницы:   1 2 3 4

S46E ©   (2006-07-18 08:36:00) 

Задача: паралельный пинг всех ip в списке Hosts без зависания программы.

Код который имеется:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,
 IdIcmpClient;

type
 TForm1 = class(TForm)
   Icmp: TIdIcmpClient;
   Button1: TButton;
   hosts: TMemo;
   Log: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

TNew = class(TThread)
 private
   n: integer;
   procedure AddStr;
   { Private declarations }
 protected
 procedure Execute; override;
end;

var
 Form1: TForm1;
 New, New2: TNew;

implementation

{$R *.dfm}

procedure TNew.Execute;
begin
Synchronize(AddStr);
end;

procedure TNew.AddStr;
begin
Form1.Icmp.Host:=Form1.Hosts.Lines[n];
Form1.Icmp.Ping('');
Form1.Log.Lines.Add('Ping '+Form1.Icmp.ReplyStatus.FromIpAddress+'______RTTime: '+InttoStr(Form1.Icmp.ReplyStatus.MsRoundTripTime)+'_______TTL: '+InttoStr(Form1.Icmp.ReplyStatus.TimeToLive));
end;

{---}

procedure TForm1.Button1Click(Sender: TObject);
begin
New := TNew.Create(true);
New.FreeOnTerminate := true;
New.Priority := tpNormal;
New2 := TNew.Create(true);
New2.FreeOnTerminate := true;
New2.Priority := tpNormal;
New.n:=0;
New2.n:=1;
New.Resume;
New2.Resume;
end;

end.


S46E   (2006-07-20 15:52:00) [61]

хм..чую isasa ©   (18.07.06 10:33) [2] :)))


StriderMan   (2006-07-20 15:51:00) [62]

Я думаю сюда надо копать

ИзСправки:

Call any methods that access a VCL component and update a form only from within the main VCL thread by passing them to the Synchronize method


S46E   (2006-07-20 15:41:00) [63]

procedure TNew.Execute;
var
s: string;
Pinger: TIdIcmpClient;
begin
Pinger := TIdIcmpClient.Create(nil);
 try
 Pinger.Host:=Form1.Hosts.Lines[n];
 Pinger.Ping('');
 s:=Pinger.ReplyStatus.FromIpAddress;
 if s='0.0.0.0' then s:=Form1.Hosts.Lines[n]+' íå îòâå÷àåò';
 Form1.Log.Lines.Add('Ping '+s+'______RTTime: '+InttoStr(Pinger.ReplyStatus.MsRoundTripTime)+'_______TTL: '+InttoStr(Pinger.ReplyStatus.TimeToLive));
 finally
 Pinger.Free
 end;
end;

{---}

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
New: TNew;
begin
for i:=0 to Form1.hosts.Lines.Count-1 do begin
 New := TNew.Create(true);
 New.n:=i;
 New.FreeOnTerminate := true;
 New.Priority := tpNormal;
 New.Resume;
 end;
end;


Извиняюсь за "промидлений".


S46E   (2006-07-20 15:39:00) [64]

Да, спасибо, все работает !
Теперь уже другая проблемка - лог формируется коряво + если пинг засел на 5 секунд(т.е. не пингуется) то в логе машина пишет сразу пинг того кто пингуется вместо него. т.е. например список:
192.168.2.1 (on)
192.168.2.244 (off)
то в логе без промидлений выходит:
Ping 192.168.2.1______RTTime: 0_______TTL: 64
Ping 192.168.2.1______RTTime: 0_______TTL: 64

Есть мнение что это связано с потоками.


StriderMan   (2006-07-20 15:29:00) [65]


> результат правда тот же))

1. То что я писал по поводу переменной Pinger касается и переменной New. объяви ее в обработчике кнопки.
2.
> Pinger.Host:=Form1.Hosts.Lines[New.n];

Pinger.Host:=Form1.Hosts.Lines[n];(New - не надо. класс и так знает что у него есть поле "n")
3.
>  try
>  Pinger.Free
>  finally
>  end;

все объекты разрушаются/создаются по такой схеме:
obj := TObject.Create;
try
 ... здесь все действия с объектом
finally
 obj.Free;
end;


S46E   (2006-07-20 15:26:00) [66]

> Кстати, зачем создавать класс TPinger который полностью повторяет предка?
Блин. Я ж думал еще зачем это..моя невнимательность. Думал как создать "динамически"? Посмотрел как создается поток и так же создал клиент..нада убрать. лишнее.


StriderMan   (2006-07-20 15:22:00) [67]


> S46E ©   (20.07.06 15:15) [10]

пардон за грубость :)

получилось что-нибудь?

Кстати, зачем создавать класс TPinger который полностью повторяет предка?


S46E   (2006-07-20 15:21:00) [68]

procedure TNew.Execute;
var
s: string;
Pinger: TPinger;
begin
Pinger := TPinger.Create(nil);
Pinger.Host:=Form1.Hosts.Lines[New.n];
Pinger.Ping('');
s:=Pinger.ReplyStatus.FromIpAddress;
if s='0.0.0.0' then s:=Form1.Hosts.Lines[New.n]+' íå îòâå÷àåò';
Form1.Log.Lines.Add('Ping '+s+'______RTTime: '+InttoStr(Pinger.ReplyStatus.MsRoundTripTime)+'_______TTL: '+InttoStr(Pinger.ReplyStatus.TimeToLive));
 try
 Pinger.Free
 finally
 end;
end;

{---}

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i:=0 to Form1.hosts.Lines.Count-1 do begin
 New := TNew.Create(true);
 New.n:=i;
 New.FreeOnTerminate := true;
 New.Priority := tpNormal;
 New.Resume;
 end;
end;


результат правда тот же)) в каждой строке выходит пинг последнего хоста в списке.


S46E   (2006-07-20 15:15:00) [69]

вот такой у меня бредогенератор..что-ж, спасибо.


StriderMan   (2006-07-20 15:09:00) [70]


> var
>  Form1: TForm1;
>  New: TNew;
>  Pinger: TPinger;
>
> implementation
>
> {$R *.dfm}
>
> procedure TNew.Execute;
> var
> s: string;
> begin
> Pinger := TPinger.Create(Form1);
> Pinger.Host:=Form1.Hosts.Lines[New.n];


жуткий бред!!!!

Pinger у тебя глобальнаяперменная, и каждый поток ее переназначает, что будет - одному богу известно. опиши ее в процедуре .Execute. После использования - разрушай, причем в конструкции try..finally. И вконструкторе не надо указывать Form1, укажи nil.


S46E   (2006-07-20 14:58:00) [71]

Сейчас код представляет собой:
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient,
 IdIcmpClient;

type
 TForm1 = class(TForm)
   Button1: TButton;
   hosts: TMemo;
   Log: TMemo;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

TNew = class(TThread)
 private
 n: integer;
   { Private declarations }
 protected
 procedure Execute; override;
end;

TPinger = class(TIdIcmpClient)
 private
   { Private declarations }
 protected
end;

var
 Form1: TForm1;
 New: TNew;
 Pinger: TPinger;

implementation

{$R *.dfm}

procedure TNew.Execute;
var
s: string;
begin
Pinger := TPinger.Create(Form1);
Pinger.Host:=Form1.Hosts.Lines[New.n];
Pinger.Ping('');
s:=Pinger.ReplyStatus.FromIpAddress;
if s='0.0.0.0' then s:=Form1.Hosts.Lines[New.n]+' не отвечает';
Form1.Log.Lines.Add('Ping '+s+'______RTTime: '+InttoStr(Pinger.ReplyStatus.MsRoundTripTime)+'_______TTL: '+InttoStr(Pinger.ReplyStatus.TimeToLive));
end;

{---}

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i:=0 to Form1.hosts.Lines.Count-1 do begin
 New := TNew.Create(true);
 New.n:=i;
 New.FreeOnTerminate := true;
 New.Priority := tpNormal;
 New.Resume;
 end;
end;

end.


Проходит цикл и выводит многократный пинг одного и того же адреса, нежели пинг каждого из списка..в чем суть?:)


Ketmar   (2006-07-18 20:45:00) [72]

>S46E ©   (18.07.06 19:08) [6]
сильно советую не читать жёлтой литературы от подозрительных авторов при этом. лучше родной help -- там всё доступно описано. да ещё и примеры дают в каталоге Demos.


S46E   (2006-07-18 19:08:00) [73]

Спасибо. Такие шедевры будут пока дельфи не потеряет свою привлекательность, начал изучать потоки только сегодня.


DrPass   (2006-07-18 18:38:00) [74]


> Неужели такие шедевры будут всегда...

По крайней мере, до тех пор, пока не пожелтеет и рассыпется последний томик Архангельского...


Piter   (2006-07-18 18:19:00) [75]

S46E ©   (18.07.06 8:36)
procedure TNew.Execute;
begin
Synchronize(AddStr);
end;


Блин... Неужели такие шедевры будут всегда...


DrPass   (2006-07-18 10:34:00) [76]

При использовании Syncronize ни о какой параллельности речи быть не может - все потоки будут ждать друг друга в очереди. Создавай экземпляр TIdICMP динамически в execute потока, и с его помощью пингуй


isasa   (2006-07-18 10:33:00) [77]

Раздели(выведи из синхронизации) сам пинг и вывод его результатов.
Кстати здесь неплохо(для вывода) работает SendMessage.


Dmitrij_K   (2006-07-18 10:29:00) [78]

Синхронизация происходит в основном потоке.


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо