PDA

Ver la Versión Completa : Ping a varias ips


Ike0
17-09-2016, 00:47:53
Buenas noches!!

Alguien me puede ayudar? Quiero hacer que un Tpanel cambie de color dependiendo si la ip responde al ping o no.

Estoy utilizando TIdIcmpClient pero no se como funciona realmente.

Me echáis una mano?

Gracias

Ike0
17-09-2016, 01:40:17
Bueno ya conseguí hacer que al pulsar un boton se ponga el Panel verde o rojo dependiendo de si existe o no el Ping. Lo he hecho con esto:

Evento OnReply de TIdIcmpClient:

procedure TForm1.IdIcmpClient1Reply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
begin
if IdIcmpClient1.ReplyStatus.BytesReceived = 0 then
begin
panel1.color:=clRed
end
else begin
Panel1.color:=clGreen;
end;
end;



Evento OnClick del TButton:

procedure TForm1.Button1Click(Sender: TObject);
begin
IdIcmpClient1.Ping;
end;


Sabiendo esto, ahora quiero saber como hacer el ping automaticamente, es decir, con un boton iniciar y/o parar la labor de hacer ping.

Gracias

Ike0
17-09-2016, 02:01:03
Creo que ya lo conseguí... si no es correcto el uso del Ttimer hacedmelo saber.

de momento esta resuelto así:

dos Botones (Iniciar, Parar)

Botón Iniciar:

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
form1.Timer1.Enabled:=true;
end;


Botón Parar

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
form1.Timer1.Enabled:=false;
form1.Panel1.Color:=clBtnFace;
End;

El Timer desactivado por defecto...

procedure TForm1.Timer1Timer(Sender: TObject);
begin
IdIcmpClient1.Ping;
end;


Siguiente paso.... hacer esto a un numero indefinido de IPs. Cual es la mejor forma de hacerlo?

Gracias

Neftali [Germán.Estévez]
19-09-2016, 11:12:49
En mi página tienes un par de ejemplos para realizar PING.
Uno utilizando ICMP y el otro WMI. Uno de ellos utiliza threads, cosa que te puede interesar si vas a realizar PING a múltiples servidores.

http://neftali.clubdelphi.com/server-ping-utilizando-wmi/
http://neftali.clubdelphi.com/ping-threaded-usando-icmp-dll/

Son antiguas, y compiladas con versión 6 de Delphi si no recuerdo mal, pero deberían funcionar en las versiones nuevas sin mayores problemas.

Ike0
20-09-2016, 01:30:46
Que pez estoy...

Siguiendo con el modo en que empece este programita, a partir de 8 o 9 direcciones Ips se empieza a relentizar la cosa no me imagino cuando este programa este haciendo ping a 200 ips.

Se solucionaría esta "lentitud" con los threads (hilos)?

Neftali [Germán.Estévez]
20-09-2016, 08:19:36
Correcto.
Debes utilizar hilos. Solventarás la velocidad y que el programa se quede "colgado", pero tendrás más consumo de memoria.

Ike0
21-09-2016, 02:12:33
Échame un cable cuando puedas Neftali. Nunca use hilos, no pido que me lo hagas sino que me guíes un poco más ;-)

(No puedo colgar imágenes ni hipervínculos aun )

Tenemos dos botones como explique (Iniciar y Parar) que lo unico que hacen es iniciar el TTimer

BOTON INICIAR
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
form1.Timer1.Enabled:=true;
end;



BOTON PARAR
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
form1.Timer1.Enabled:=false;
form1.Panel1.Color:=clBtnFace;
End;

el TTimer al ser iniciado, cada segundo y medio hace lo siguiente;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Form2.C002.ping;
Form2.C003.ping;
Form2.C004.ping;

end;



cada C00X es un TIdIcmpclient que en su evento OnReply hace lo siguiente;

procedure TForm2.C002Reply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
begin
if C002.ReplyStatus.BytesReceived = 0 then
begin
Form1.PP002.Fill.Color :=TAlphaColorRec.Red;
end
else begin
Form1.PP002.Fill.color:= TAlphaColorRec.Chartreuse;
end;
end;

Solo he puesto el del TiDicmplient C002, el de el C003 es idéntico y así hasta el infinito y mas allá.

El programa sin hilos, lo que hace es hace ping al 002, termina pero no pone su cuadradito en verde, tiene que esperar a que termine con el C003, y asi sucesivamente hasta que llegue al TidIcmpclient con la ultima IP.

Hasta aquí todo claro. Por lo que leo, los hilos o Threads, pueden ayudarme a hacer las llamadas a cada evento Onreply paralelamente pero no se como hacerlo. Puedes ayudarme o guiarme un poco mas?

Gracias de antemano

Casimiro Notevi
21-09-2016, 09:57:12
(No puedo colgar imágenes ni hipervínculos aun )
Utiliza el truco de eliminar una letra, ejemplo: _ww.loquesea.com/imagen.png
Y un moderador lo cambiará.

Neftali [Germán.Estévez]
21-09-2016, 10:34:26
Por lo que leo, los hilos o Threads, pueden ayudarme a hacer las llamadas a cada evento Onreply paralelamente pero no se como hacerlo.

La operación de ping, al igual que muchas otras, el problema que tiene es que durante su ejecución detiene el programa. La llamada en si, no el código que se ejecuta en el OnReply.
Por lo tanto, lo que ganamos ejecutando threads es que al poner la tarea que "bloquea" en el thread, se bloquea ese thread, pero no el programa principal.

Lo primero que debes hacer es crear el componente TIdIcmpClient por código. Modifica tu programa para hecerlo y comprueba que funciona.
Una vez lo tengas se trata de crear un thread que:

(1) En el create cree el componente por código.
(2) Le tendrás que pasar algunos valores como parámetro y luego recoger la respuesta.
(3) En el métdo Execute lanzar el ping.
(4) Capturar el OnReply dentro del Thread
(5) Crear un procedimiento OnTerminate, al que irá a parar el thread cuando acabe, que será el que pinte verde/rojo según el estado.

Puedes realizar algunas pruebas e ir poniendo el código aquí. Te lo vamos revisando y corrigiendo si hare falta.

Ike0
21-09-2016, 23:51:42
Ufff.. es complicado esto para mi, voy a ir mascando poco a poco jejejjeje

Neftali, sacando conclusiones, creo entender ahora mejor tu primera respuesta, leyendo la ultima. Corrígeme si me equivoco:

Primer Paso: Lo primero que debes hacer es crear el componente TIdIcmpClient por código
Leyendo tu primera respuesta (segundo link de tu pagina "ICMP") mi componente TIdIcmpClient podría ser la unidad raw_ping.pas o unit1.pas?

Gracias

Neftali [Germán.Estévez]
22-09-2016, 09:27:51
Ufff.. es complicado esto para mi, voy a ir mascando poco a poco jejejjeje

Neftali, sacando conclusiones, creo entender ahora mejor tu primera respuesta, leyendo la ultima. Corrígeme si me equivoco:

Primer Paso: Lo primero que debes hacer es crear el componente TIdIcmpClient por código
Leyendo tu primera respuesta (segundo link de tu pagina "ICMP") mi componente TIdIcmpClient podría ser la unidad raw_ping.pas o unit1.pas?

Gracias

Digamos que esa unit es mucho más compleja, es más sencillo que uses el componente visual. Yo la dejaría por ahora.
Crear un componente en ejecución es mucho más fácil. Los componentes que sueltas en un formulario se crean automáticamente al crear el formulario, pero también puedes crearlos por código (te servirás porque luego deberás hacerlo en el thread).

Por ejemplo, en el club puedes encontrar muchos códigos para crear diferentes componentes en ejecución:
http://www.clubdelphi.com/foros/showpost.php?p=370206&postcount=16
http://www.clubdelphi.com/foros/showthread.php?p=277758
http://www.clubdelphi.com/foros/showpost.php?p=132384&postcount=2

Algo más.

Por ejemplo, en este hilo tienes código para un thread utilizando otro componente de las Indy.
https://www.clubdelphi.com/foros/showthread.php?t=81584
En ese ejemplo [nlsGarcia] ha creado un Thread con un componente TidFTP. PPero para la creación y la estructura del Thread, te puede servir.

En este también hay algo similar con un thread.
Revisa los código porque te pueden servir de base para el tuyo. Intenta entenderlos.
https://www.clubdelphi.com/foros/showthread.php?t=72316

(1) Verás como en ambos se crea el componente en cuestión en el Create de la clase del thread.
(2) Luego hay un método Execute, que es el que se encarga de realizar el trabajo. Descargar un fichero o en tu caso realizar el PING.

Rocio90
22-09-2016, 13:15:42
Gracias:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
IdIcmpClient1.Ping;
end;

Ike0
23-09-2016, 02:51:08
Manos a la Obra... os iré contando para que me corrijáis.

Gracias