
Aplicación se congela al hacer Pings masivo
#1
Posted 14 March 2009 - 04:52 PM
Saludos.
#2
Posted 14 March 2009 - 05:08 PM
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
Posted 14 March 2009 - 05:10 PM
Saludos.
#4
Posted 14 March 2009 - 06:56 PM
#5
Posted 15 March 2009 - 11:22 AM
http://delphi.about....l/aa081503a.htm
Saludos.
#6
Posted 15 March 2009 - 11:50 AM
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
Posted 15 March 2009 - 11:57 AM
[Pascal Error] Main.pas(1): Unable to invoke Code Completion due to errors in source code
Saludos.
#8
Posted 15 March 2009 - 12:04 PM
[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
Posted 15 March 2009 - 12:40 PM

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

#12
Posted 15 March 2009 - 12:54 PM
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
Posted 15 March 2009 - 01:01 PM

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

Saludos,
#14
Posted 15 March 2009 - 01:05 PM
¿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
Posted 15 March 2009 - 02:40 PM
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
Posted 15 March 2009 - 04:05 PM
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
Posted 15 March 2009 - 04:14 PM

#18
Posted 15 March 2009 - 06:49 PM
Saludos.
#19
Posted 16 March 2009 - 06:14 AM
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
Posted 16 March 2009 - 07:01 AM
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;