Implementieren von PING ohne Verwendung von Raw-Sockets

Windows unterstützt ein Internet Control Message Protocol (ICMP), um festzustellen, ob ein bestimmter Host verfügbar ist oder nicht. ICMP ist ein Netzwerkschichtprotokoll, das Flusskontrolle, Fehlermeldungen, Routing und andere Daten zwischen Internet-Hosts bereitstellt. ICMP wird hauptsächlich von Anwendungsentwicklern für einen Netzwerk-Ping verwendet.

Was ist ein Ping?

Ein Ping ist der Vorgang des Sendens einer Echo-Nachricht an eine IP-Adresse und des Lesens der Antwort, um eine Verbindung zwischen zu überprüfen TCP / IP-Hosts. Wenn Sie eine neue Anwendung schreiben, ist es besser, die in implementierte Winsock 2-Raw-Sockets-Unterstützung zu verwenden Indy, zum Beispiel.

Beachten Sie jedoch, dass Raw-Sockets für Windows NT- und Windows 2000-Implementierungen Sicherheitsüberprüfungen unterliegen und nur Mitgliedern der Administratorgruppe zugänglich sind. Icmp.dll bietet Funktionen, mit denen Entwickler Internet-Ping-Anwendungen auf Windows-Systemen ohne Winsock 2-Unterstützung schreiben können.

instagram viewer

Beachten Sie, dass die Winsock 1.1 WSAStartup-Funktion aufgerufen werden muss, bevor die von ICMP.DLL bereitgestellten Funktionen verwendet werden. Wenn Sie dies nicht tun, schlägt der erste Aufruf von IcmpSendEcho mit dem Fehler 10091 (WSASYSNOTREADY) fehl.

Unten finden Sie den Quellcode der Ping-Einheit. Hier sind zwei Anwendungsbeispiele.

Beispiel 1: Code-Snippet

Verwendet Klingeln;...
const
ADP_IP = '208.185.127.40'; (* http://delphi.about.com *)
beginIf
Klingeln. Ping (ADP_IP) dann ShowMessage ('Über Delphi Programming erreichbar!');
Ende
;

Beispiel 2: Delphi-Programm im Konsolenmodus

Unser nächstes Beispiel ist ein Konsolenmodus Delphi-Programm das verwendet die Ping-Einheit:. Hier ist die Quelle der Ping-Einheit:

Einheit Klingeln;
Schnittstellen

Windows, SysUtils, Klassen;
Art

TSunB = gepackte Aufzeichnung
s_b1, s_b2, s_b3, s_b4: Byte;
Ende
;
TSunW = gepackte Aufzeichnung
s_w1, s_w2: Wort;
Ende
;
PIPAddr = ^ TIPAddr;
TIPAddr = Aufzeichnung
Fall
ganze Zahl von
0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: Langwort);
Ende
; IPAddr = TIPAddr;
Funktion
IcmpCreateFile: THandle; stdcall; extern 'icmp.dll';
Funktion
IcmpCloseHandle (icmpHandle: THandle): boolean;
stdcall
; extern 'icmp.dll'
Funktion
IcmpSendEcho
(IcmpHandle: THandle; Zieladresse: IPAddr;
RequestData: Pointer; RequestSize: Smallint;
RequestOptions: Zeiger;
ReplyBuffer: Pointer;
ReplySize: DWORD;
Zeitüberschreitung: DWORD): DWORD; stdcall; extern 'icmp.dll';
Funktion
Ping (InetAddress: Zeichenfolge): Boolescher Wert;
Implementierungsanwendungen

WinSock;
Funktion
Holen(var AInput: Zeichenfolge;
const
ADelim: Zeichenfolge = ' ';
const
ADelete: Boolean = true)
: Zeichenfolge;
var

iPos: Integer;
Start
wenn
ADelim = # 0 dann fang an
// AnsiPos funktioniert nicht mit # 0

iPos: = Pos (ADelim, AInput);
Ende sonst beginnen

iPos: = Pos (ADelim, AInput);
Ende
;
wenn
iPos = 0 dann fang an
Ergebnis: = AInput;
wenn
ADelete dann fang an
AInput: = '';
Ende
;
Ende sonst beginnen

Ergebnis: = Kopieren (AInput, 1, iPos - 1);
wenn
ADelete dann fang an
Löschen (AInput, 1, iPos + Länge (ADelim) - 1);
Ende
;
Ende
;
Ende
;
Verfahren
TranslateStringToTInAddr (AIP: Zeichenfolge; var AInAddr);
var

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

WSAStartup ($ 101, GInitData);
Versuchen

phe: = GetHostByName (PChar (AIP));
wenn
Zugewiesen (phe) dann fang an
pac: = phe ^ .h_addr_list ^;
wenn
Zugewiesen (pac) dann
Start
mit
TIPAddr (AInAddr) .S_un_b fange an
s_b1: = Byte (pac [0]); s_b2: = Byte (pac [1]); s_b3: = Byte (pac [2]); s_b4: = Byte (pac [3]);
Ende
;
Ende
sonst
Start
erziehen
Ausnahme. Create ('Fehler beim Abrufen der IP von HostName');
Ende
;
Ende
sonst
Start
erziehen
Ausnahme. Create ('Fehler beim Abrufen des Hostnamens');
Ende
;
außer

FillChar (AInAddr, SizeOf (AInAddr), # 0);
Ende
; WSACleanup;
Ende
;
Funktion
Ping (InetAddress: Zeichenfolge): Boolescher Wert;
var

Griff: THandle;
InAddr: IPAddr;
DW: DWORD;
rep: Array[1..128] von Byte;
Start

Ergebnis: = falsch; Handle: = IcmpCreateFile;
wenn
Handle = INVALID_HANDLE_VALUE dann
Ausgang;
TranslateStringToTInAddr (InetAddress, InAddr);
DW: = IcmpSendEcho (Handle, InAddr, Null, 0, Null, @rep, 128, 0); Ergebnis: = (DW 0); IcmpCloseHandle (Handle);
Ende
;​
Ende
.