PING implementeren zonder Raw Sockets te gebruiken

Windows ondersteunt een Internet Control Message Protocol (ICMP) om te bepalen of een bepaalde host beschikbaar is of niet. ICMP is een netwerklaagprotocol dat stroomcontrole, foutmeldingen, routering en andere gegevens tussen internethosts levert. ICMP wordt voornamelijk gebruikt door applicatie-ontwikkelaars voor een netwerk-ping.

Wat is een ping?

Een ping is het proces van het verzenden van een echo-bericht naar een IP-adres en het lezen van het antwoord om een ​​verbinding tussen TCP / IP-hosts te verifiëren. Als u een nieuwe applicatie schrijft, is het beter om de Winsock 2 raw sockets-ondersteuning te gebruiken, bijvoorbeeld geïmplementeerd in Indy.

Houd er echter rekening mee dat voor Windows NT- en Windows 2000-implementaties Raw Sockets onderworpen zijn aan beveiligingscontroles en alleen toegankelijk zijn voor leden van de groep van de beheerder. Icmp.dll biedt functionaliteit waarmee ontwikkelaars internet-ping-toepassingen op Windows-systemen kunnen schrijven zonder Winsock 2-ondersteuning. 

Merk op dat de Winsock 1.1 WSAStartup-functie moet worden aangeroepen voordat de functies worden gebruikt die worden blootgesteld door ICMP.DLL. Als u dit niet doet, mislukt de eerste aanroep van IcmpSendEcho met fout 10091 (WSASYSNOTREADY).

Hieronder vindt u de broncode van de Ping-eenheid. Hier zijn twee voorbeelden van gebruik.

Voorbeeld 1: codefragment

toepassingen Ping;… 
const
ADP_IP = '208.185.127.40'; (* http://delphi.about.com *)
beginIf
Ping.Ping (ADP_IP) vervolgens ShowMessage ('Over Delphi Programming bereikbaar!');
einde
;

Voorbeeld 2: Delphi-programma in consolemodus

Ons volgende voorbeeld is een Delphi-programma in de consolemodus dat de Ping-eenheid gebruikt:. Hier is de bron van de Ping-eenheid:

eenheid Ping; 
interfaceuses

Windows, SysUtils, Classes;
type

TSunB = ingepakt record
s_b1, s_b2, s_b3, s_b4: byte;
einde
;
TSunW = ingepakt record
s_w1, s_w2: word;
einde
;
PIPAddr = ^ TIPAddr;
TIPAddr = Vermelding
geval
geheel getal van
0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: longword);
einde
; IPAddr = TIPAddr;
functie
IcmpCreateFile: THandle; STDCALL; extern 'Icmp.dll';
functie
IcmpCloseHandle (icmpHandle: THandle): boolean;
STDCALL
; extern 'Icmp.dll'
functie
IcmpSendEcho
(IcmpHandle: THandle; DestinationAddress: IPAddr;
RequestData: Pointer; RequestSize: Smallint;
RequestOptions: pointer;
ReplyBuffer: Pointer;
ReplySize: DWORD;
Timeout: DWORD): DWORD; STDCALL; extern 'Icmp.dll';
functie
Ping (InetAddress: draad): boolean;
implementationuses

WinSock;
functie
Fetch (var AInput: draad;
const
ADelim: draad = ";
const
ADelete: Boolean = true)
: draad;
var

iPos: geheel getal;
beginnen
als
ADelim = # 0 begin dan
// AnsiPos werkt niet met # 0

iPos: = Pos (ADelim, AInput);
einde anders beginnen

iPos: = Pos (ADelim, AInput);
einde
;
als
iPos = 0 begin dan
Resultaat: = AInput;
als
ADelete begin dan
AInput: = ";
einde
;
einde anders beginnen

resultaat: = Kopiëren (AInput, 1, iPos - 1);
als
ADelete begin dan
Verwijderen (AInput, 1, iPos + Lengte (ADelim) - 1);
einde
;
einde
;
einde
;
procedure
TranslateStringToTInAddr (AIP: draad; var AInAddr);
var

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

WSAStartup ($ 101, GInitData);
proberen

phe: = GetHostByName (PChar (AIP));
als
Toegewezen (phe) thenbegin
pac: = phe ^ .h_addr_list ^;
als
Toegewezen (pac) vervolgens
beginnen
met
TIPAddr (AInAddr) .S_un_b beginnen
s_b1: = Byte (pac [0]); s_b2: = Byte (pac [1]); s_b3: = Byte (pac [2]); s_b4: = Byte (pac [3]);
einde
;
einde
anders
beginnen
raise
Exception.Create ('Fout bij ophalen van IP van HostName');
einde
;
einde
anders
beginnen
raise
Exception.Create ('Fout bij het ophalen van HostName');
einde
;
behalve

FillChar (AInAddr, SizeOf (AInAddr), # 0);
einde
, WSACleanup;
einde
;
functie
Ping (InetAddress: draad): boolean;
var

Handvat: THandle;
InAddr: IPAddr;
DW: DWORD;
rep: rangschikking[1… 128] van byte;
beginnen

result: = false; Handle: = IcmpCreateFile;
als
Handle = INVALID_HANDLE_VALUE vervolgens
Uitgang;
TranslateStringToTInAddr (InetAddress, InAddr);
DW: = IcmpSendEcho (Handle, InAddr, nul, 0, nul, @rep, 128, 0); Resultaat: = (DW 0); IcmpCloseHandle (handle);
einde
;
einde
.