Implémentation de PING sans utiliser de socket brut

Windows prend en charge un protocole ICMP (Internet Control Message Protocol) pour déterminer si un hôte particulier est disponible ou non. ICMP est un protocole de couche réseau qui fournit le contrôle de flux, les messages d'erreur, le routage et d'autres données entre les hôtes Internet. ICMP est principalement utilisé par les développeurs d'applications pour un ping réseau.

Qu'est-ce qu'un ping?

Un ping est le processus d'envoi d'un message d'écho à une adresse IP et de lecture de la réponse pour vérifier une connexion entre les hôtes TCP / IP. Si vous écrivez une nouvelle application, il vaut mieux utiliser le support des sockets bruts Winsock 2, implémenté dans Indy, par exemple.

Notez cependant que pour les implémentations Windows NT et Windows 2000, les sockets bruts sont soumis à des contrôles de sécurité et sont accessibles uniquement aux membres du groupe de l'administrateur. Icmp.dll fournit des fonctionnalités qui permettent aux développeurs d'écrire des applications ping Internet sur les systèmes Windows sans prise en charge de Winsock 2. 

Notez que la fonction Winsock 1.1 WSAStartup doit être appelée avant d'utiliser les fonctions exposées par ICMP.DLL. Si vous ne le faites pas, le premier appel à IcmpSendEcho échouera avec l'erreur 10091 (WSASYSNOTREADY).

Ci-dessous, vous pouvez trouver le code source de l'unité Ping. Voici deux exemples d'utilisation.

Exemple 1: extrait de code

les usages Ping;… 
const
ADP_IP = '208.185.127.40'; (* http://delphi.about.com *)
beginIf
Ping.Ping (ADP_IP) ensuite ShowMessage ('À propos de la programmation Delphi accessible!');
fin
;

Exemple 2: programme Delphi en mode console

Notre exemple suivant est un programme Delphi en mode console qui utilise l'unité Ping:. Voici la source de l'unité Ping:

unité Ping; 
interfaceuses

Windows, SysUtils, Classes;
type

TSunB = record emballé
s_b1, s_b2, s_b3, s_b4: octet;
fin
;
TSunW = record emballé
s_w1, s_w2: mot;
fin
;
PIPAddr = ^ TIPAddr;
TIPAddr = record
Cas
entier de
0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: mot long);
fin
; IPAddr = TIPAddr;
une fonction
IcmpCreateFile: THandle; stdcall; externe 'icmp.dll';
une fonction
IcmpCloseHandle (icmpHandle: THandle): booléen;
stdcall
; externe 'icmp.dll'
une fonction
IcmpSendEcho
(IcmpHandle: THandle; DestinationAddress: IPAddr;
RequestData: Pointer; RequestSize: Smallint;
RequestOptions: pointeur;
ReplyBuffer: Pointeur;
ReplySize: DWORD;
Délai d'expiration: DWORD): DWORD; stdcall; externe 'icmp.dll';
une fonction
Ping (InetAddress: chaîne): booléen;
mise en œuvre

WinSock;
une fonction
Récupérer (var AInput: chaîne;
const
ADelim: chaîne = ";
const
ADelete: Boolean = true)
: chaîne;
var

iPos: Entier;
commencer
si
ADelim = # 0 alors commence
// AnsiPos ne fonctionne pas avec # 0

iPos: = Pos (ADelim, AInput);
fin sinon commencer

iPos: = Pos (ADelim, AInput);
fin
;
si
iPos = 0 alors commence
Résultat: = AInput;
si
ADelete alors commence
AInput: = ";
fin
;
fin sinon commencer

résultat: = Copie (AInput, 1, iPos - 1);
si
ADelete alors commence
Supprimer (AInput, 1, iPos + Length (ADelim) - 1);
fin
;
fin
;
fin
;
procédure
TranslateStringToTInAddr (AIP: chaîne; var AInAddr);
var

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

WSAStartup (101 $, GInitData);
essayer

phe: = GetHostByName (PChar (AIP));
si
Attribué (phe) puis commencer
pac: = phe ^ .h_addr_list ^;
si
Attribué (pac) ensuite
commencer
avec
TIPAddr (AInAddr) .S_un_b commence
s_b1: = octet (pac [0]); s_b2: = octet (pac [1]); s_b3: = octet (pac [2]); s_b4: = octet (pac [3]);
fin
;
fin
autre
commencer
élever
Exception.Create ('Erreur lors de l'obtention de l'adresse IP à partir du nom d'hôte');
fin
;
fin
autre
commencer
élever
Exception.Create ('Erreur lors de l'obtention du nom d'hôte');
fin
;
sauf

FillChar (AInAddr, SizeOf (AInAddr), # 0);
fin
; WSACleanup;
fin
;
une fonction
Ping (InetAddress: chaîne): booléen;
var

Poignée: THandle;
InAddr: IPAddr;
DW: DWORD;
représentant: tableau[1… 128] de octet;
commencer

result: = false; Handle: = IcmpCreateFile;
si
Handle = INVALID_HANDLE_VALUE ensuite
Sortie;
TranslateStringToTInAddr (InetAddress, InAddr);
DW: = IcmpSendEcho (Handle, InAddr, néant, 0, néant, @rep, 128, 0); Résultat: = (DW 0); IcmpCloseHandle (Handle);
fin
;
fin
.