
Aplicación se congela al hacer Pings masivo
#1
Escrito 14 marzo 2009 - 04:52
Saludos.
#2
Escrito 14 marzo 2009 - 05:08
Si implementas el ping dentro de un thread puedes realizar 10, 20 o incluso 30 pings simultáneos. Además mientras se están realizando tu aplicación no parecerá congelada.
#3
Escrito 14 marzo 2009 - 05:10
Saludos.
#4
Escrito 14 marzo 2009 - 06:56
#5
Escrito 15 marzo 2009 - 11:22
http://delphi.about....l/aa081503a.htm
Saludos.
#6
Escrito 15 marzo 2009 - 11:50
Ahora bien... hice una prueba con la IP que muestra de ejemplo y no veo el cartelito... ¿será que la IP de delphi about ya no es esa?


Saludos,
#7
Escrito 15 marzo 2009 - 11:57
[Pascal Error] Main.pas(1): Unable to invoke Code Completion due to errors in source code
Saludos.
#8
Escrito 15 marzo 2009 - 12:04
[Error] Ping.pas(39): Identifier redeclared: 'Ping' [Error] Ping.pas(112): Identifier redeclared: 'Ping' [Error] Ping.pas(39): Unsatisfied forward or external declaration: '.1' [Fatal Error] Unit1.pas(7): Could not compile used unit 'Ping.pas'
Y lo que tuve que hacer fue reemplazar el nombre de la función Ping por otro... digamos IfPing. Luego para llamar a la función lo único que hice es esto:
procedure TForm1.Button1Click(Sender: TObject); const ADP_IP = '208.185.127.40'; (* http://delphi.about.com *) begin If ifPing(ADP_IP) then ShowMessage('About Delphi Programming reachable!'); end;
Y por lo que estuve viendo en Who is, la IP de delphi.about es esa... No me muestra el cartelito...
Saludos,
#9
Escrito 15 marzo 2009 - 12:40

Saludos.
#10
Escrito 15 marzo 2009 - 12:44
Saludos,
#11
Escrito 15 marzo 2009 - 12:45
Esruve probando haciendo ping a otras IP amigo, y funciona,... a veces.
Saludos,
Ah pues, eso indica que deberé seguir buscando...

#12
Escrito 15 marzo 2009 - 12:54
Yo al igual que Domingo creo que el tema pasa por emplear hilos. Yo mucho del manejo de hilos no tengo idea, sólo cierta teoría: se declara un descendiente de la clase TThread, se sobrescribe el método Execute y en él se implementan las rutinas necesarias (en este caso el ping). Luego se instancian algunos objetos de esta clase y se mandan a ejecutar.
Saludos,
#13
Escrito 15 marzo 2009 - 01:01

A lo mejor podemos estudiarlo y ver el modo de adaptarlo a lo que necesitas... y te evitas usar un componente

Saludos,
#14
Escrito 15 marzo 2009 - 01:05
¿A ti, a pesar de que se congela... te funciona el código original, con el componente TIdIcmpClient?
Yo al igual que Domingo creo que el tema pasa por emplear hilos. Yo mucho del manejo de hilos no tengo idea, sólo cierta teoría: se declara un descendiente de la clase TThread, se sobrescribe el método Execute y en él se implementan las rutinas necesarias (en este caso el ping). Luego se instancian algunos objetos de esta clase y se mandan a ejecutar.
Saludos,
El código original funciona perfectamente, el problema es que si hay muchos relojes fuera de servicio se congela por minutos hasta que termine y repite el proceso.
Saludos.
#15
Escrito 15 marzo 2009 - 02:40
unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient, IdIcmpClient; type TThreadPing = class(TThread) private Respuesta: String; //resultado protected procedure Execute; override; public constructor Create(IP: String); end; TForm1 = class(TForm) Button1: TButton; pE01: TIdIcmpClient; procedure IdIcmpClient1Reply(ASender: TComponent; const AReplyStatus: TReplyStatus); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; cIP: String; implementation {$R *.dfm} constructor TThreadPing.Create(IP: String); begin cIP := IP; //guarda la IP en una variable privada inherited Create(True); end; procedure SetReloj(Host: String; S: TLabel; Recibe: TIdIcmpClient); begin Recibe.Host := cIP; with Recibe.ReplyStatus do begin case ReplyStatusType of rsEcho: begin S.Caption := 'Conectado'; S.Font.Color := clBlue; end; rsTimeOut: begin S.Caption := 'Apagado'; S.Font.Color := clRed; end; rsErrorUnreachable: begin S.Caption := 'Sin Conección'; S.Font.Color := clRed; end; end; end; end; procedure TThreadPing.Execute; begin Synchronize(SetReloj); end; procedure TForm1.Button1Click(Sender: TObject); var DIR: TThreadPing; begin DIR.Create('127.0.0.1'); end; end.
No logro echarlo a andar, se queda en el Execute con "[Error] Main.pas(66): There is no overloaded version of 'Synchronize' that can be called with these arguments", estoy seguro que está totalmente mal

Saludos.
#16
Escrito 15 marzo 2009 - 04:05
unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdRawBase, IdRawClient, IdIcmpClient; type TThreadPing = class(TThread) private Respuesta: String; //resultado procedure SetReloj(Host: String; S: TLabel; Recibe: TIdIcmpClient); protected procedure Execute; override; public constructor Create(IP: String); end; TForm1 = class(TForm) Button1: TButton; pE01: TIdIcmpClient; procedure IdIcmpClient1Reply(ASender: TComponent; const AReplyStatus: TReplyStatus); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; cIP: String; implementation {$R *.dfm} constructor TThreadPing.Create(IP: String); begin cIP := IP; //guarda la IP en una variable privada inherited Create(True); end; procedure TThreadPing.SetReloj(Host: String; S: TLabel; Recibe: TIdIcmpClient); begin Recibe.Host := cIP; with Recibe.ReplyStatus do begin case ReplyStatusType of rsEcho: begin S.Caption := 'Conectado'; S.Font.Color := clBlue; end; rsTimeOut: begin S.Caption := 'Apagado'; S.Font.Color := clRed; end; rsErrorUnreachable: begin S.Caption := 'Sin Conección'; S.Font.Color := clRed; end; end; end; end; procedure TThreadPing.Execute; begin Synchronize(SetReloj); end; procedure TForm1.Button1Click(Sender: TObject); var DIR: TThreadPing; begin DIR.Create('127.0.0.1'); end; end.
Debes meter el procedure SetReloj dentro del TThread, ya que Syncronize trabaja con TThreadMetod
#17
Escrito 15 marzo 2009 - 04:14

#18
Escrito 15 marzo 2009 - 06:49
Saludos.
#19
Escrito 16 marzo 2009 - 06:14
1. El metodo syncronize recibe un procedimiento sin parametros es por eso lo de tu error.
2. Te sugiero crear dentro del thread el Componente de las Indy.
3.
procedure TForm1.Button1Click(Sender: TObject); var DIR: TThreadPing; begin DIR.Create('127.0.0.1'); DiR.Resume; // Con esto le indicas que inicie el thread. porque el parametro true del constructor lo inicia pausado. end;
Saludos.
#20
Escrito 16 marzo 2009 - 07:01
Yo no tengo mucha experiencia con Threads pero si he hecho uso de ellos en un par de aplicaciones ultimamente. y te pudo decir esto.
1. El metodo syncronize recibe un procedimiento sin parametros es por eso lo de tu error.
2. Te sugiero crear dentro del thread el Componente de las Indy.
3.delphi
procedure TForm1.Button1Click(Sender: TObject); var DIR: TThreadPing; begin DIR.Create('127.0.0.1'); DiR.Resume; // Con esto le indicas que inicie el thread. porque el parametro true del constructor lo inicia pausado. end;
Saludos.
Se me fue adelante Kipow, es correcta la indicación, no debes pasar un método con parámetros a Syncronize.
type TThreadMethod = procedure of object;