Delphi usa o ICMP para detectar se o host remoto está vivo
2005-03-10 JLBNET
Na comunicação de rede, geralmente é necessário determinar se o host remoto está vivo para determinar a operação realizada na próxima parte. Ele pode ser implementado diretamente usando o protocolo ICMP, mas muitos detalhes do protocolo precisam ser considerados, o que é mais problemático de implementar. Existem funções prontas na biblioteca ICMP que vem com o Windows, basta preencher a estrutura de dados correspondente antes do uso.
A seguir, a estrutura de dados a ser usada. Essas estruturas MSDN têm declarações no Formulário C, e a forma de Delphi é dada aqui.
// a estrutura de dados do protocolo usada
PIPOPTIONIMFO = ^TipoptionInfo;
TipOptionInfo = registro embalado
Ttl: byte; // tempo de vida
TOS: byte; // tipo de serviço, tipo de solicitação
Bandeiras: byte; // loteria
OptionsSize: byte; // Comprimento da opção
OptionsData: pchar; // Dados de opções
fim;
PicmPechoreply = ^ticmPechoreply;
TicmPechoreply = registro embalado // ICMP Return Information
Endereço: DWORD; // Endereço IP
Status: dword; // status
Rtt: dword;
DataSize: Word; // Comprimento dos dados
Reservado: palavra; // reserva
Dados: ponteiro; // dados
Opções: TipOptionInfo; // Área de opções
fim;
// Declaração de função na biblioteca dinâmica
TicmpCreatefile = função: THANDLE;
TicmpCloseHandle = função (icmphandle: THANDLE): boolean;
TicmPsendecho = função (icmphandle: thandle; destinoAddress: dword;
Solicitação: Ponteiro;
ResponderBuffer: Ponteiro;
// a declaração variável a ser usada
hicmpdll, hicmp: thandle;
Wsadata: Twsadata;
ICMPCreateFile: ticmpCreateFile;
IcmpCloseHandle: ticmpCloseHandle;
ICMPSENDECHO: TICMPSENDECHO;
// Destip: O endereço remoto a ser detectado é como 192.168.1.1
Procedimento f_checkonline (destip: string);
var
IPOPT: TipOptionInfo; // Opções de IP do pacote
Ipaddr: dword;
preqdata, prevData: pchar;
Pipe: PicmPechoreply; // Buffer de resposta de eco ICMP
Fsize: dword;
Mystring: string;
Ftimeout: dword;
Buffersize: dword;
I: Inteiro;
Começar
hicmpdll: = loadlibrary ('icmp.dll'); // clique na biblioteca dinâmica do ICMP
Se hicmpdll <> nulo, então
Começar
WSASTARTUP (US $ 101, WSADATA); // Inicialize a pilha de protocolos de rede
@Icmpcreatefile: = getProcaddress (hicmpdll, 'icmpcreatefile'); //, por favor, a função de exportação na biblioteca dinâmica
@IcmpCloseHandle: = getProcaddress (hicmpdll, 'icmpCloseHandle');
@IcMPSENDECHO: = getProcaddress (hicmpdll, 'icmPsendecho');
hicmp: = icmpcreatefile; // Crie uma alça ICMP
Ipaddr: = inet_addr (pchar (destip)); // Obtenha o endereço IP do host remoto a ser detectado
Fsize: = 40;
Buffersize: = sizeof (ticmPechoreply) + fsize;
GetMem (prevData, fsize);
GetMem (tubo, buffersize);
Preenchchar (tubo^, sizeof (tubo^), 0);
tubo^.data: = prevData;
Mystring: = 'oi, online?'; // string arbitrária
preqdata: = pchar (mystring);
Preenchchar (ipopt, sizeof (iPOpt), 0);
IPopt.ttl: = 64;
Ftimeout: = 500; // Tempo de espera
i: = icmpsendecho (hicmp, ipaddr, preqdata, comprimento (mystring), @IPOPT, tubo, buffersize, ftimeout); // Se houver um retorno, o valor de retorno indica o número de respostas recebidas. Se 0 significa nenhuma resposta, o host não pode alcançar
Freemem (prevData);
Freemem (tubo);
IcmpCloseHandle (hicmp);
Freelibrary (hicmpdll); // Libere a biblioteca dinâmica
Wsacleanup (); // Limpe a pilha de protocolo
fim;
fim;