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:
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":
Indicaremos la carpeta y el nombre del fichero a guardar:
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.
Anuncios