Delphi usa ICMP para detectar si el host remoto está vivo
2005-03-10 JLBNET
En la comunicación de red, a menudo es necesario determinar si el host remoto está vivo para determinar la operación realizada en la siguiente parte. Se puede implementar directamente utilizando el protocolo ICMP, pero se deben considerar muchos detalles del protocolo, lo cual es más problemático de implementar. Hay funciones preparadas en la biblioteca ICMP que viene con Windows, solo poca la estructura de datos correspondiente antes de usar.
La siguiente es la estructura de datos que se utilizará. Estas estructuras MSDN tienen declaraciones en la Forma C, y la forma de Delphi se da aquí.
// La estructura de datos del protocolo utilizada
PipOptionInfo = ^tipOptionInfo;
TipoptionInfo = registro empacado
Ttl: byte; // Life Time
TOS: byte; // tipo de servicio, tipo de solicitud
Banderas: byte; // lotería
Opciones Size: Byte; // Longitud de la opción
OptionsData: pchar; // Datos de opciones
fin;
PicmpechorePly = ^ticmpechorePly;
TicmpechorePly = Registro empacado // Información de retorno de ICMP
Dirección: Dword; // dirección IP
Estado: dword; // status
Rtt: dword;
DataSize: Word; // Longitud de datos
Reservado: palabra; // reserva
Datos: puntero; // datos
Opciones: TipoptionInfo; // Área de opciones
fin;
// Declaración de funciones en la biblioteca dinámica
TicmpCreateFile = Función: Thandle;
TicmpCloseHandle = function (icmphandle: thandle): boolean;
TicmpsendeCo = function (icmphandle: Thandle; DestinationAddress: dword;
RequestData: puntero;
ResponderBuffer: Pointer;
// La declaración de la variable a ser utilizada
hicmpdll, hicmp: thandle;
wsadata: twsadata;
IcmpCreateFile: ticmpCreateFile;
ICMPCloseHandle: TicmpCloseHandle;
ICMPSENDECHO: ticmpsendecho;
// Destip: la dirección remota que se detectará es como 192.168.1.1
Procedimiento F_CheckOnline (Destip: String);
varilla
IPopt: tipOptionInfo; // Opciones de IP del paquete
Ipaddr: dword;
preQData, PrevData: PCHAR;
tubería: picmpechoreply; // buffer de respuesta icmp echo
Fsize: dword;
MyString: cadena;
Ftimeout: dword;
BufferSize: DWORD;
I: entero;
Comenzar
hicmpdll: = LoadLibrary ('icmp.dll'); // Haga clic en la biblioteca dinámica ICMP
Si hicmpdll <> nulo entonces
Comenzar
WSASTARTUP ($ 101, WSADATA); // Inicializar la pila de protocolo de red
@IcmpCreateFile: = getProcAddress (hicmpdll, 'icmpCreateFile'); // Por favor, la función de exportación en la biblioteca dinámica
@IcmpcloseHandle: = getProcAddress (hicmpdll, 'icmpCloseHandle');
@ICMPSEnDECHO: = getProcAddress (hicmpdll, 'icmpsendeCo');
hicmp: = icmpCreateFile; // Crear un mango ICMP
Ipaddr: = inet_addr (pchar (destip)); // Obtenga la dirección IP del host remoto para ser detectado
Fsize: = 40;
BufferSize: = sizeOf (ticMpechorePly) + fsize;
GetMem (PrevSdata, FSize);
GetMem (tubería, buffersize);
Relleno (tubería^, sizeOf (tubería^), 0);
tubería^.data: = PrevData;
Mystring: = 'hola, en línea?'; // cadena arbitraria
preqData: = Pchar (myString);
Fillchar (iPopt, sizeof (iPopt), 0);
Ipopt.ttl: = 64;
Ftimeout: = 500; // Tiempo de espera
I: = ICMPSEnDECHO (HICMP, iPADDR, preqData, longitud (myString), @ipopt, pipe, bufferSize, ftimeout); // Si hay una devolución, el valor de retorno indica el número de respuestas recibidas. Si 0 significa que no hay respuesta, el anfitrión no puede alcanzar
Freemem (PrevSdata);
Freemem (tubería);
ICMPCLOSEHANDLE (HICMP);
Freelibrary (hicmpdll); // Liberar la biblioteca dinámica
Wsacleanup (); // limpia la pila de protocolo
fin;
fin;