Wdrażanie PING bez użycia surowych gniazd

Windows obsługuje protokół ICMP (Internet Control Message Protocol) w celu ustalenia, czy dany host jest dostępny. ICMP to protokół warstwy sieci, który zapewnia kontrolę przepływu, komunikaty o błędach, routing i inne dane między hostami internetowymi. ICMP jest używany głównie przez twórców aplikacji do pingowania sieci.

Co to jest ping?

Ping to proces wysyłania wiadomości echa na adres IP i odczytywania odpowiedzi w celu weryfikacji połączenia między Hosty TCP / IP. Jeśli piszesz nową aplikację, lepiej będzie skorzystać z obsługi surowych gniazd Winsock 2, zaimplementowanych w Indy, na przykład.

Należy jednak pamiętać, że w przypadku implementacji Windows NT i Windows 2000 Raw Sockets podlegają kontroli bezpieczeństwa i są dostępne tylko dla członków grupy administratora. Icmp.dll zapewnia funkcjonalność, która pozwala programistom pisać internetowe aplikacje ping w systemach Windows bez obsługi Winsock 2.

Należy pamiętać, że funkcja WSAStartup Winsock 1.1 musi zostać wywołana przed użyciem funkcji ujawnionych przez ICMP.DLL. Jeśli tego nie zrobisz, pierwsze wywołanie IcmpSendEcho zakończy się niepowodzeniem z błędem 10091 (WSASYSNOTREADY).

instagram viewer

Poniżej znajduje się kod źródłowy jednostki ping. Oto dwa przykłady użycia.

Przykład 1: fragment kodu

wykorzystuje Świst;...
const
ADP_IP = „208.185.127.40”; (* http://delphi.about.com *)
beginIf
Świst. Ping (ADP_IP) następnie ShowMessage („Osiągalne informacje o programowaniu Delphi!”);
koniec
;

Przykład 2: Program Delphi w trybie konsoli

Nasz następny przykład to tryb konsoli Program Delphi korzystający z jednostki ping:. Oto źródło jednostki ping:

jednostka Świst;
interfejsy

Windows, SysUtils, Klasy;
rodzaj

TSunB = zapakowany rekord
s_b1, s_b2, s_b3, s_b4: bajt;
koniec
;
TSunW = zapakowany rekord
s_w1, s_w2: słowo;
koniec
;
PIPAddr = ^ TIPAddr;
TIPAddr = rekord
walizka
liczba całkowita z
0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: longword);
koniec
; IPAddr = TIPAddr;
funkcjonować
IcmpCreateFile: THandle; stdcall; zewnętrzny „icmp.dll”;
funkcjonować
IcmpCloseHandle (icmpHandle: THandle): boolean;
stdcall
; zewnętrzny „icmp.dll”
funkcjonować
IcmpSendEcho
(IcmpHandle: THandle; DestinationAddress: IPAddr;
RequestData: Pointer; RequestSize: Smallint;
RequestOptions: wskaźnik;
ReplyBuffer: Wskaźnik;
ReplySize: DWORD;
Limit czasu: DWORD): DWORD; stdcall; zewnętrzny „icmp.dll”;
funkcjonować
Ping (adres inet: strunowy): boolean;
implementacje

WinSock;
funkcjonować
Sprowadzać(var A Wejście: strunowy;
const
ADelim: strunowy = ' ';
const
ADelete: Boolean = true)
: strunowy;
var

iPos: liczba całkowita;
zaczynać
gdyby
ADelim = # 0 potem zacznij
// AnsiPos nie działa z numerem 0

iPos: = Pos (ADelim, AInput);
koniec jeszcze zacząć

iPos: = Pos (ADelim, AInput);
koniec
;
gdyby
iPos = 0 potem zacznij
Wynik: = AInput;
gdyby
C Usuń potem zacznij
AInput: = '';
koniec
;
koniec jeszcze zacząć

wynik: = Kopiuj (AInput, 1, iPos - 1);
gdyby
C Usuń potem zacznij
Usuń (AInput, 1, iPos + długość (ADelim) - 1);
koniec
;
koniec
;
koniec
;
procedura
TranslateStringToTInAddr (AIP: strunowy; var AInAddr);
var

phe: PHostEnt; pac: PChar; GInitData: TWSAData;
zaczynać

WSAStartup (101 USD, GInitData);
próbować

phe: = GetHostByName (PChar (AIP));
gdyby
Przypisany (phe) wtedy zacznij
pac: = phe ^ .h_addr_list ^;
gdyby
Przypisany (pac) następnie
zaczynać
z
TIPAddr (AInAddr) .S_un_b zaczynać
s_b1: = Bajt (pac [0]); s_b2: = Bajt (pac [1]); s_b3: = Bajt (pac [2]); s_b4: = Bajt (pac [3]);
koniec
;
koniec
jeszcze
zaczynać
podnieść
Wyjątek. Utwórz („Błąd podczas pobierania adresu IP z nazwy hosta”);
koniec
;
koniec
jeszcze
zaczynać
podnieść
Wyjątek. Utwórz („Błąd podczas pobierania nazwy hosta”);
koniec
;
z wyjątkiem

FillChar (AInAddr, SizeOf (AInAddr), # 0);
koniec
; WSACleanup;
koniec
;
funkcjonować
Ping (adres inet: strunowy): boolean;
var

Uchwyt: THandle;
InAddr: IPAddr;
DW: DWORD;
reprezentant: szyk[1..128] z bajt;
zaczynać

wynik: = fałsz; Uchwyt: = IcmpCreateFile;
gdyby
Uchwyt = INVALID_HANDLE_VALUE następnie
Wyjście;
TranslateStringToTInAddr (InetAddress, InAddr);
DW: = IcmpSendEcho (uchwyt, InAddr, zero, 0, zero, @rep, 128, 0); Wynik: = (DW 0); IcmpCloseHandle (uchwyt);
koniec
;​
koniec
.