Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Ping A Un Cliente Y Accion (https://www.clubdelphi.com/foros/showthread.php?t=51284)

cristian.gomez 11-12-2007 18:43:26

Ping A Un Cliente Y Accion
 
Estimados:
Estoy en un pequeño "pozo negro".
Me han pedido hacer una pequeña aplicación, que primero haga un PING a uno o varios PC de nuestra LAN, y dependiendo de la respuesta (activo o no), hacer una u otra acción pre determinada.
Estoy trabajando con Delphi 7 SE, pero también tengo el Delphi 2005.
Sé que existe un componente que puede hacer esto, pero nunca lo he usado, y tampoco he encontrado información o ejemplos prácticos en google. Si alguien ha usado o sabe como hacerlo, le agradecería que me pueda ayudar.
Otro punto importante, es que no quiero instalar ningún programa en el CLIENTE. Este programa solo estará en un PC del administrador y desde ahi debe poder hacer todo lo necesario.

Desde ya muchas gracias,

Saludos cordiales

CG.

white_zombie 11-12-2007 19:53:32

Hola, un componente para hacer ping a una dirección es el IdIcmpClient de las indy.

Es bastante facil de usar. Por ejemplo.

Código:

IdIcmpClient1.Host:='192.168.1.9';
IdIcmpClient1.ReceiveTimeout:=2000;
IdIcmpClient1.Ping('Prueba de IP correcta',0);

Para comprobar si esta activo el equipo.

Código:

IdIcmpClient1.ReplyStatus.FromIpAddress
o
Código:

IdIcmpClient1.ReplyStatus.BytesReceived

Neftali [Germán.Estévez] 12-12-2007 10:30:18

Hay un poco de "morralla" porque lo estoy usando dentro de un programa, pero esto te debería servir:

Código Delphi [-]
procedure TPingThread.Execute;
var
  rp:TReplyStatus;
begin

  Self.IdIcmp := TIdIcmpClient.Create(nil);
  // proteccion
  try
    Self.IdIcmp.Host := Self.FIPServer;
    Self.IdIcmp.ReceiveTimeout := 2000;
    // Asignar Evento
    IdIcmp.OnReply := PingReply;

    ini := Now;

    try
      // Lanzar el PING
      IdIcmp.Ping;

    except
      on E:EIdSocketError do begin
        rp := TReplyStatus.Create;
        rp.FromIpAddress := '0.0.0.0';
        rp.ToIpAddress := '0.0.0.0';
        rp.ReplyStatusType := rsError;
        rp.Msg := E.Message;
        PingReply(IdIcmp, rp);
      end;
    end;

  finally
    FreeAndNil(Self.IdIcmp);
  end;
end;

En PingReply o en el evento OnReply tienes los datos de la respuesta, tal y como te han dicho.

fide 31-03-2008 21:30:31

Por que cuando intento hacer ping con ese componente de la Indy desde una seccion que no es administrador en Windows XP SP2 me aparece el siguiente error.

Código:

Socket Error # 10013
Access denied.

Si alguien sabe que pasa, por favor que me ayuda!. Esto pasa solo si no soy administrador....

jesconsa 23-11-2011 18:34:03

Hola. Eso pasa como ya habras visto por otros sitios porque la manera que tiene Indy de hacer el ping es a traves del Winsock 2 que tiene elementos de seguridad que le obligan a pasar por el Firewall. En cambio el Ping que utilizas en Windows es a traves de una dll, ICMP.DLL creo recordar, y esta dll es con raw sockets no sujetas a esas directivas de seguridad, por eso puedes hacer un ping desde el interprete de comandos sin tener que tocar el Firewall. Es la primera vez que hablo por aqui, no seais muy duros conmigo.

Saludos

jesconsa 23-11-2011 19:00:54

Perdon, ICMP.DLL no es raw sockets. Una pregunta por si alguien me da alguna pista. LLevo algunos dias con IcmpClient de Indy y todo va bien, o casi. Lo que hago es una llamada en bucle para crear threads para hacer pings a equipos. No he reinventado la rueda sino que he estado mirando una rutina en Internet de alguien que ya la hizo. la rutina del ejecutable del Thread es la siguiente:


procedure TPingThread.Execute;
var
rp:TReplyStatus;
begin
FErrorCount := 0;
FAlarmed := false;

Ping := TIdIcmpClient.Create(nil);
Ping.FreeOnRelease;
Ping.Host := FHost;

Ping.PacketSize:=16;
Ping.OnReply := PingReply;
Ping.ReceiveTimeout := 1000;


try
// Lanzar el PING
Ping.Ping;
finally
FreeAndNil(Ping);
end;

end;


procedure TPingThread.PingReply(ASender: TComponent; const AReplyStatus: TReplyStatus);
begin

if (AReplyStatus.ReplyStatusType = rsTimeOut) or (AReplyStatus.ReplyStatusType = rsErrorUnreachable) then begin
Form1.Memo1.Lines.Add('Equipo caido.');
end else begin
Form1.Memo1.Lines.Add('Equipo OK');
end;

end;


Si comienzo el thread con Resume o Start para dos equipos (dos threads) resulta que si el primero tiene conexion y el segundo no, lo muestra bien en el Memo ,...pero si el primero NO tiene conexion y el segundo si, en el Memo se ve como el segundo da su mensaje de 'Equipo OK' y al llegar el Reply del primero (Timeout) me aparece tambien 'Equipo OK' como si fuera el otro equipo, es decir, cuando llega el timeout de uno es como si los Threads no estuvieran bien difrenciados y toma los datos del ultimo Thread que se ejecuto.......He probado con Synchronize y este tipo de cosas pero no he funcionado....

Alguna pista please?

Muchas gracias
Jesus

Casimiro Notevi 23-11-2011 19:48:09

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración.


La franja horaria es GMT +2. Ahora son las 15:21:29.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi