Vida

Implementación de PING sin usar sockets sin procesar

Implementación de PING sin usar sockets sin procesar

Windows admite un Protocolo de mensajes de control de Internet (ICMP) para determinar si un host particular está disponible o no. ICMP es un protocolo de capa de red que ofrece control de flujo, mensajes de error, enrutamiento y otros datos entre hosts de Internet. ICMP es utilizado principalmente por los desarrolladores de aplicaciones para un ping de red.

¿Qué es un ping?

Un ping es el proceso de enviar un mensaje de eco a una dirección IP y leer la respuesta para verificar una conexión entre los hosts TCP / IP. Si está escribiendo una nueva aplicación, será mejor utilizar el soporte de sockets sin procesar Winsock 2, implementado en Indy, por ejemplo.

Sin embargo, tenga en cuenta que para las implementaciones de Windows NT y Windows 2000, los Sockets sin procesar están sujetos a controles de seguridad y solo son accesibles para los miembros del grupo de administradores. Icmp.dll proporciona una funcionalidad que permite a los desarrolladores escribir aplicaciones de ping de Internet en sistemas Windows sin compatibilidad con Winsock 2.

Tenga en cuenta que la función Winsock 1.1 WSAStartup debe llamarse antes de usar las funciones expuestas por ICMP.DLL. Si no hace esto, la primera llamada a IcmpSendEcho fallará con el error 10091 (WSASYSNOTREADY).

A continuación puede encontrar el código fuente de la unidad Ping. Aquí hay dos ejemplos de uso.

Ejemplo 1: fragmento de código

usos Ping; ...
const
ADP_IP = '208.185.127.40'; (* //delphi.about.com *)
comenzar si
Ping.Ping (ADP_IP) luego ShowMessage ('Acerca de la programación de Delphi alcanzable');
fin
;

Ejemplo 2: Programa Delphi en modo consola

Nuestro siguiente ejemplo es un programa Delphi en modo consola que utiliza la unidad Ping:. Aquí está la fuente de la unidad Ping:

unidad Ping;
interfaces

Windows, SysUtils, Clases;
tipo

TSunB = registro lleno
s_b1, s_b2, s_b3, s_b4: byte;
fin
;
TSunW = registro lleno
s_w1, s_w2: palabra;
fin
;
PIPAddr = ^ TIPAddr;
TIPAddr = grabar
caso
entero de
0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: palabra larga);
fin
; IPAddr = TIPAddr;
función
IcmpCreateFile: THandle; stdcall; externo 'icmp.dll';
función
IcmpCloseHandle (icmpHandle: THandle): boolean;
stdcall
; externo 'icmp.dll'
función
IcmpSendEcho
(IcmpHandle: THandle; DestinationAddress: IPAddr;
RequestData: puntero; RequestSize: Smallint;
RequestOptions: puntero;
ReplyBuffer: Puntero;
ReplySize: DWORD;
Tiempo de espera: DWORD): DWORD; stdcall; externo 'icmp.dll';
función
Ping (InetAddress: cuerda): booleano;
implementación

WinSock;
función
Ha podido recuperar(var AInput: cuerda;
const
ADelim: cuerda =";
const
ADeletear: booleano = verdadero)
: cuerda;
var

iPos: entero;
empezar
Si
ADelim = # 0 entonces comienza
// AnsiPos no funciona con # 0

iPos: = Pos (ADelim, AInput);
fin más comienza

iPos: = Pos (ADelim, AInput);
fin
;
Si
iPos = 0 entonces comienza
Resultado: = AInput;
Si
ADelete entonces comienza
AInput: = ";
fin
;
fin más comienza

resultado: = Copiar (AInput, 1, iPos - 1);
Si
ADelete entonces comienza
Eliminar (AInput, 1, iPos + Longitud (ADelim) - 1);
fin
;
fin
;
fin
;
procedimiento
TranslateStringToTInAddr (AIP: cuerda; var AInAddr);
var

phe: PHostEnt; pac: PChar; GInitData: TWSAData;
empezar

WSAStartup ($ 101, GInitData);
tratar

phe: = GetHostByName (PChar (AIP));
Si
Asignado (phe) entonces comenzar
pac: = phe ^ .h_addr_list ^;
Si
Asignado (pac) luego
empezar
con
TIPAddr (AInAddr) .S_un_b empieza
s_b1: = Byte (pac0); s_b2: = Byte (pac1); s_b3: = Byte (pac2); s_b4: = Byte (pac3);
fin
;
fin
más
empezar
aumento
Exception.Create ('Error al obtener IP de HostName');
fin
;
fin
más
empezar
aumento
Exception.Create ('Error al obtener HostName');
fin
;
excepto

FillChar (AInAddr, SizeOf (AInAddr), # 0);
fin
; WSACleanup;
fin
;
función
Ping (InetAddress: cuerda): booleano;
var

Manija: THandle;
InAddr: IPAddr;
DW: DWORD;
representante: formación1… 128 de byte;
empezar

resultado: = falso; Identificador: = IcmpCreateFile;
Si
Handle = INVALID_HANDLE_VALUE luego
Salida;
TranslateStringToTInAddr (InetAddress, InAddr);
DW: = IcmpSendEcho (Handle, InAddr, nulo, 0, nulo, @rep, 128, 0); Resultado: = (DW 0); IcmpCloseHandle (Handle);
fin
;​
fin
.