Utilizamos cookies propias y de terceros. [Más información sobre las cookies].
Política de cookies
Proyecto AjpdSoft

· Inicio
· Buscar
· Contactar
· Cookies
· Descargas
· Foros
· Historia
· Nosotros
· Temas
· Top 10
· Trucos
· Tutoriales
· Wiki

Delphi: AjpdSoft Ping ICMP
AjpdSoft


Añadida a la sección Descargas la aplicación AjpdSoft Ping ICMP: realiza un ping (comprueba el estado de la conexión con un equipo remoto por medio de los paquetes de solicitud de eco y de respuesta de eco). Permite indicar el tamaño en bytes del paquete a enviar, la IP o el hostname (nombre de red) del equipo remoto (tanto de la LAN como de Internet), el número de intentos de ping que se realizará y el tiempo en milisegundos entre intento. Muestra los resultados en pantalla y permite guardarlos en fichero de texto. Liberamos el código fuente - source code en Borland Delphi 6 100% Open Source.



Definición de Ping

La utilidad de ping comprueba el estado de la conexión con un equipo remoto por medio de los paquetes de solicitud de eco y de respuesta de eco (ambos definidos en el protocolo de red ICMP) para determinar si un sistema IP específico es accesible en una red. Es útil para diagnosticar los errores en redes o enrutadores IP.

Muchas veces se utiliza para medir la latencia o tiempo que tardan en comunicarse dos puntos remotos.

Con el comando ping podemos ver lo "lejos" que está un equipo verificando los TTL (Tiempo de Vida o Time To Live es un concepto usado para indicar por cuántos nodos puede pasar un paquete antes de ser descartado por la red o devuelto a su origen).

El TTL o TimeToLive es utilizado en el paquete IP de manera que los routers puedan analizarlo y actuar según su contenido. Si un router recibe un paquete con un TTL igual a uno o cero, no lo envía a través de sus puertos, sino que notifica vía ICMP a la dirección IP origen que el destino se encuentra "muy alejado". Si un paquete es recibido por un router que no es el destino, éste decrementa el valor del TTL en uno y envía el paquete al siguiente router (next hop).

En el protocolo IP, esta información se almacena en un campo de 8 bits. El valor óptimo para aprovechar el rendimiento en Internet del TTL es de 128.

 

Características más importantes de AjpdSoft Ping ICMP

  • Aplicación de muy sencillo manejo, muy fácil e intuitiva, todas las opciones están en una misma ventana.
  • La aplicación ha sido desarrollada en el lenguaje de programación Borland Delphi 6.
  • No necesita instalación, es suficiente con ejecutar el fichero pingICMP.exe.
  • Admite parámetros, pasándole como parámetro la IP o el hostname del equipo remoto.
  • Permite especificar el tamaño en bytes del paquete a enviar.
  • Permite indicar el número de repeticiones del ping que se realizará.
  • Permite personalizar el tiempo entre repetición en milisegundos.
  • Se puede guardar el resultado del ping en un fichero de texto.
  • Guarda automáticamente los equipos a los que se les haya hecho ping en una lista desplegable.

 

AjpdSoft Ping ICMP en funcionamiento

AjpdSoft Ping ICMP realiza un ping a un equipo de nuestra LAN o de Internet. Para ello será suficiente con abrir el fichero pingICMP.exe e introducir en "IP/Hostname" la dirección IP o el nombre de red (hostname) del equipo al que queramos realizarle el ping. A continuación pulsaremos en "Ping" y la aplicación nos irá mostrando el resultado de los intentos de ping que vaya realizando:

AjpdSoft Ping ICMP

Podremos personalizar las siguientes opciones:

  • Bytes: número de bytes que se enviarán en el paquete del ping (por defecto 32).
  • Tiempo: número de milisegundos entre cada paquete enviado (por defecto 1000).
  • Nº paquetes: número de intentos de ping que se realizarán (número de paquetes que se enviarán).

La aplicación, una vez que haya finalizado el número de paquetes a enviar para el ping, mostrará un resultado como este:

05/05/2010 13:12:52 Realizando ping a ajpdsoft.com [OK]
05/05/2010 13:12:52 Realizando ping ajpdsoft.com [82.98.144.32]
05/05/2010 13:12:52 Respuesta desde 82.98.144.32: bytes = 32 tiempo=16ms TTL=53
05/05/2010 13:12:53 Respuesta desde 82.98.144.32: bytes = 32 tiempo=17ms TTL=53
05/05/2010 13:12:54 Respuesta desde 82.98.144.32: bytes = 32 tiempo=16ms TTL=53
Estadísticas de ping para 82.98.144.32:
Paquetes:
+ Enviados = 3
+ Recibidos = 3
+ Perdidos = 0
Tiempos aproximados de envío y recepción:
+ Mínimo = 16 ms
+ Máximo = 17 ms
+ Media = 16ms

Podremos guardar estos datos pulsando en el botón "Guardar":

AjpdSoft Ping ICMP

Indicaremos la carpeta y el nombre del fichero a guardar:

AjpdSoft Ping ICMP

 

 

Instalación y configuración de AjpdSoft Ping ICMP

AjpdSoft Ping ICMP no necesita instalación, se puede ejecutar directamente el fichero pingICMP.exe. La aplicación necesitará la librería icmp.dll que viene con Windows por defecto.

 

 

Datos técnicos de AjpdSoft Ping ICMP

Esta aplicación ha sido desarrollada en el lenguaje de programación Borland Delphi 6. La aplicación utiliza la función del API de Windows IcmpSendEcho, por lo que requiere de la librería icmp.dll que viene por defecto con Windows.

Si eres desarrollador de software y te has registrado en nuestra web (si aún no te has registrado puedes hacerlo desde aquí gratuitamente) puedes descargar el código fuente 100% Open Source (completo y totalmente gratuito) en Borland (ahora Codegear) Delphi 6:

AjpdSoft Ping ICMP (Código fuente Open Source en Borland Delphi 6)

AjpdSoft Ping ICMP ha sido testeada y funciona correctamente en equipos con sistemas operativos:Windows XP, Windows 2000 Server, Windows Server 2003, Windows Vista y Windows 7 (Seven).

 

Para usuarios desarrolladores de software

La aplicación utiliza los siguientes componentes (para Delphi 6):

 

A quién va dirigida AjpdSoft Ping ICMP

La aplicación AjpdSoft Ping ICMP va dirigida a administradores de sistemas, administradores de red y usuarios que quieran realizar ping de forma más efectiva que utilizando el comando ping de Windows. Esta aplicación utiliza el mismo procedimiento pero permite modificar algunos parámetros.

También puede ser útil para estudiantes que tengan que realizar algún proyecto de ejemplo de desarrollo de aplicación que realice un ping.

Anexo

  • Código fuente (source code) de la aplicación completa:

Unidad "UnidadMenuPrincipal.pas":

unit UnidadMenuPrincipal;

{$R WinXP.res}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms,
  Dialogs, StdCtrls, aping, ComCtrls,
  shellapi, Buttons, ThemeMgr, inifiles;

type
  TformMenuPrincipal = class(TForm)
    txtResultado: TMemo;
    LWEB: TLabel;
    bGuardar: TBitBtn;
    ThemeManager1: TThemeManager;
    dlGuardar: TSaveDialog;
    bSalir: TBitBtn;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    txtIP: TComboBox;
    txtBytes: TEdit;
    txtTiempo: TEdit;
    txtNumRepeticiones: TEdit;
    Label4: TLabel;
    btPing: TBitBtn;
    opLimpiar: TCheckBox;
    procedure btPingClick(Sender: TObject);
    procedure txtIPKeyPress(Sender: TObject; var Key: Char);
    procedure LWEBClick(Sender: TObject);
    procedure bGuardarClick(Sender: TObject);
    procedure bSalirClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  ip_option_information = record
    Ttl : byte;
    Tos : byte;
    Flags : byte;
    OptionsSize : byte;
    OptionsData : pointer;
  end;

  ICMP_ECHO_REPLY = record
    Address : IPAddr;
    Status : ULONG;
    RoundTripTime : ULONG;
    DataSize : Word;
    Reserved : Word;
    Data : Pointer;
    Options : IP_OPTION_INFORMATION;
   end;

var
 formMenuPrincipal: TformMenuPrincipal;

implementation

{$R *.dfm}

function buscarElementoComboBox (
    combo : TComboBox; elemento : string) : boolean;
var
  i : integer;
begin
  Result := false;
  for i := 0 to combo.Items.Count - 1 do
  begin
    if AnsiUpperCase(combo.Items[i]) = AnsiUpperCase(elemento) then
    begin
      Result := true;
      Exit;
    end;
  end;
end;

//lee un valor booleano de un fichero INI
function leBoolINI (clave, cadena : string; defecto : boolean) : boolean;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := readbool (clave, cadena, defecto);
  finally
    free;
  end;
end;

//lee un valor numérico de un fichero INI
function leNumINI (clave, cadena : string; defecto : Integer) : Integer;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := ReadInteger (clave, cadena, defecto);
  finally
    free;
  end;
end;

//lee un valor string de un fichero INI
function leCadINI (clave, cadena : string; defecto : String) : String;
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    result := ReadString (clave, cadena, defecto);
  finally
    free;
  end;
end;

//escribe un valor string en un fichero INI
procedure esCadINI (clave, cadena : string; valor : String);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    WriteString (clave, cadena, valor);
  finally
    free;
  end;
end;

//escribe un valor boolean en un fichero INI
procedure esBoolINI (clave, cadena : string; valor : Boolean);
begin
  with tinifile.create (changefileext(paramstr(0),'.INI')) do
  try
    WriteBool (clave, cadena, valor);
  finally
    free;
  end;
end;

procedure TformMenuPrincipal.btPingClick(Sender: TObject);
var
  Handle : THandle;
  InAddr : IPAddr;
  DW : DWORD;
  cnt : integer;
  SAddr : string;
  pnum : integer;
  minTime : longint;
  maxTime : longint;
  allTime : longint;
  stat : longint;
  PingBuf : array[0..31] of char;
  Reply : ICMP_ECHO_REPLY;
begin
  if opLimpiar.Checked then
  begin
    txtResultado.Clear;
    Refresh;
  end;

  if txtResultado.Text <> '' then
  begin
    txtResultado.Lines.Add('');
    txtResultado.Lines.Add('');
  end;

  if ping(txtIP.Text) then
  begin
    txtResultado.Lines.Add (DateTimeToStr(Now) + ' ' +
        'Realizando ping a ' + txtIP.Text + ' [OK]');
    if not buscarElementoComboBox(txtIP, txtIP.Text) then
      txtIP.Items.Add (txtIP.Text);
    txtIP.Items.SaveToFile(
        IncludeTrailingPathDelimiter (ExtractFilePath(Application.ExeName)) +
        'equipos.txt');
  end
  else
    txtResultado.Lines.Add (DateTimeToStr(Now) +
        ' Realizando ping a ' + txtIP.Text + ' [NO DISPONIBLE]');

  Handle := IcmpCreateFile;
  if Handle = INVALID_HANDLE_VALUE then
    Halt(2);
  TranslateStringToTInAddr(txtIP.Text, InAddr);

  SAddr := Format('%d.%d.%d.%d',[InAddr.S_un_b.s_b1, InAddr.S_un_b.s_b2,
      InAddr.S_un_b.s_b3, InAddr.S_un_b.s_b4]);

  txtResultado.Lines.Add (DateTimeToStr(Now) +
      Format (' Realizando ping %s [%s]',[txtIP.Text, SAddr]) );

  pnum := 0;
  minTime := MaxInt -1;
  maxTime := 0;
  AllTime := 0;

  Reply.Data := @pingBuf;
  Reply.DataSize := 32;

  for cnt := 1 to StrToInt(txtNumRepeticiones.Text) do
  begin
    DW := IcmpSendEcho(Handle, InAddr, @PingBuf, strtoint(txtBytes.text), nil, @reply,
        SizeOf(icmp_echo_reply) + strtoint(txtBytes.text), 3000);
    if DW = 0 then
       txtResultado.Lines.Add (DateTimeToStr(Now) +
           ' Tiempo de espera agotado')
    else
    begin
      txtResultado.Lines.Add (DateTimeToStr(Now) +
          (Format(' Respuesta desde %s: bytes = ' +
          txtBytes.Text + ' tiempo=%dms TTL=%d',
          [SAddr, Reply.RoundTripTime, Reply.Options.Ttl])));
      stat := Reply.RoundTripTime;
      inc(pnum);
      if minTime > stat then
        minTime := stat;
      if maxTime < stat then
        maxTime := stat;
      AllTime := AllTime + stat;
    end;
    Sleep(StrToInt(txtTiempo.Text));
  end;
  IcmpCloseHandle(Handle);

  txtResultado.Lines.Add (' Estadísticas de ping para ' + SAddr + ':');
  txtResultado.Lines.Add ('  Paquetes: ');
  txtResultado.Lines.Add ('     + Enviados  =  ' + txtNumRepeticiones.Text);
  txtResultado.Lines.Add ('     + Recibidos = ' + inttostr(pnum));
  txtResultado.Lines.Add ('     + Perdidos  = ' +
      inttostr(strtoint(txtNumRepeticiones.Text) - pnum));
  if StrToInt(txtNumRepeticiones.Text) = pnum then
  begin
    txtResultado.Lines.Add ('  Tiempos aproximados de envío y recepción:');
    txtResultado.Lines.Add ('     + Mínimo = ' +  inttostr(minTime) + ' ms');
    txtResultado.Lines.Add ('     + Máximo = ' + inttostr(maxTime) + ' ms');
    txtResultado.Lines.Add ('     + Media  = ' + inttostr(round(AllTime / pnum)) + 'ms');
  end;
end;

procedure TformMenuPrincipal.txtIPKeyPress(
    Sender: TObject; var Key: Char);
begin
  if key = #13 then
    btPingClick(Self);
end;

procedure TformMenuPrincipal.LWEBClick(Sender: TObject);
begin
  ShellExecute(Handle, Nil, PChar('http://www.ajpdsoft.com'),
      Nil, Nil, SW_SHOWNORMAL);
end;

procedure TformMenuPrincipal.bGuardarClick(Sender: TObject);
begin
  if dlGuardar.Execute then
    txtResultado.Lines.SaveToFile(dlGuardar.FileName);
end;

procedure TformMenuPrincipal.bSalirClick(Sender: TObject);
begin
  close;
end;

procedure TformMenuPrincipal.FormShow(Sender: TObject);
begin
  if ParamStr(1) <> '' then
  begin
    txtIP.Text := ParamStr(1);
    btPing.SetFocus;
  end;
end;

procedure TformMenuPrincipal.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  esCadINI('Datos', 'Equipo', txtIP.Text);
  esCadINI('Datos', 'Bytes', txtBytes.Text);
  esCadINI('Datos', 'Tiempo', txtTiempo.Text);
  esCadINI('Datos', 'Número paquetes', txtNumRepeticiones.Text);
  esBoolINI('Datos', 'Limpiar datos actuales', opLimpiar.Checked);
end;

procedure TformMenuPrincipal.FormCreate(Sender: TObject);
var
  fichero : string;
begin
  txtIP.Text := leCadINI('Datos', 'Equipo', 'localhost');
  txtBytes.Text := leCadINI('Datos', 'Bytes', '32');
  txtTiempo.Text := leCadINI('Datos', 'Tiempo', '1000');
  txtNumRepeticiones.Text := leCadINI('Datos', 'Número paquetes', '5');
  opLimpiar.Checked := leBoolINI('Datos', 'Limpiar datos actuales', false);
  fichero := IncludeTrailingPathDelimiter (
      ExtractFilePath(Application.ExeName)) + 'equipos.txt';
  if FileExists(fichero) then
    txtIP.Items.LoadFromFile(fichero);
end;

end.


 

Unidad "aping.pas":

unit aping;

interface
uses
  Windows, SysUtils, Classes;

type
  TSunB = packed record
    s_b1, s_b2, s_b3, s_b4: byte;
  end;

  TSunW = packed record
    s_w1, s_w2: word;
  end;

  PIPAddr = ^TIPAddr;
  TIPAddr = record
    case integer of
      0: (S_un_b: TSunB);
      1: (S_un_w: TSunW);
      2: (S_addr: longword);
  end;

 IPAddr = TIPAddr;

function IcmpCreateFile : THandle; stdcall; external 'icmp.dll';
function IcmpCloseHandle (icmpHandle : THandle) : boolean;
    stdcall; external 'icmp.dll'
function IcmpSendEcho (
    IcmpHandle : THandle; DestinationAddress : IPAddr;
    RequestData : Pointer; RequestSize : Smallint;
    RequestOptions : pointer;
    ReplyBuffer : Pointer;
    ReplySize : DWORD;
    Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll';


function Ping(InetAddress : string) : boolean;

procedure TranslateStringToTInAddr(AIP: string; var AInAddr);

implementation

uses
  WinSock;

function Fetch(var AInput: string; const ADelim: string = ' ';
    const ADelete: Boolean = true) : string;
var
  iPos: Integer;
begin
  if ADelim = #0 then begin
    // AnsiPos does not work with #0
    iPos := Pos(ADelim, AInput);
  end else begin
    iPos := Pos(ADelim, AInput);
  end;
  if iPos = 0 then begin
    Result := AInput;
    if ADelete then begin
      AInput := '';
    end;
  end else begin
    result := Copy(AInput, 1, iPos - 1);
    if ADelete then begin
      Delete(AInput, 1, iPos + Length(ADelim) - 1);
    end;
  end;
end;

procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
  phe: PHostEnt;
  pac: PChar;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  try
    phe := GetHostByName(PChar(AIP));
    if Assigned(phe) then
    begin
      pac := phe^.h_addr_list^;
      if Assigned(pac) then
      begin
        with TIPAddr(AInAddr).S_un_b do begin
          s_b1 := Byte(pac[0]);
          s_b2 := Byte(pac[1]);
          s_b3 := Byte(pac[2]);
          s_b4 := Byte(pac[3]);
        end;
      end
      else
      begin
        raise Exception.Create('Error al obtener la IP del equipo');
      end;
    end
    else
    begin
      raise Exception.Create('Error al obtener el nombre de red');
    end;
  except
    FillChar(AInAddr, SizeOf(AInAddr), #0);
  end;
  WSACleanup;
end;

function Ping(InetAddress : string) : boolean;
var
 Handle : THandle;
 InAddr : IPAddr;
 DW : DWORD;
 rep : array[1..128] of byte;
begin
  result := false;
  Handle := IcmpCreateFile;
  if Handle = INVALID_HANDLE_VALUE then
   Exit;
  TranslateStringToTInAddr(InetAddress, InAddr);
  DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);
  Result := (DW <> 0);
  IcmpCloseHandle(Handle);
end;

end.

 

Artículos relacionados

 

Créditos

Artículo realizado íntegramente por Alonsojpd miembro fundador del proyecto AjpdSoft.

Bookmark and Share
Anuncios


Enviado el Miércoles, 05 mayo a las 13:50:55 por ajpdsoft
Visita nuestro nuevo sitio web con programas y contenidos actualizados: Proyecto A