Delphi uses ICMP to detect whether the remote host is alive
2005-03-10 jlbnet
In network communication, it is often necessary to determine whether the remote host is alive to determine the operation performed in the next part. It can be implemented directly using the ICMP protocol, but many protocol details need to be considered, which is more troublesome to implement. There are ready-made functions in the ICMP library that comes with Windows, just populate the corresponding data structure before use.
The following is the data structure to be used. These structures MSDN have declarations in form C, and the form of Delphi is given here.
//The protocol data structure used
PipOptionInfo = ^TIPOptionInfo; // IP header options
TIPOptionInfo = packed record
TTL: Byte;//Life time
TOS: Byte;//Type of Service, request type
Flags: Byte;//Lottery
OptionsSize: Byte;//Option length
OptionsData: PChar;//Options Data
end;
PIcmpEchoReply = ^TIcmpEchoReply;
TIcmpEchoReply = packed record // ICMP Return information
Address: DWord;//IP address
Status: DWORD;//Status
RTT: DWORD;
DataSize: Word;//Data length
Reserved: Word;//Reserve
Data: Pointer;//Data
Options: TIPOptionInfo;//Options area
end;
// Function declaration in dynamic library
TIcmpCreateFile = function: THandle; stdcall; //Create ICMP handle
TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean; stdcall; //Close the ICMP handle
TIcmpSendEcho = function(IcmpHandle:THandle; DestinationAddress:DWORD;
RequestData:Pointer; RequestSize:Word; RequestOptions:PIPOptionInfo;
ReplyBuffer:Pointer; ReplySize:DWord; Timeout:DWord):DWord; stdcall;//Send ICMP probe datagram
//The variable declaration to be used
hICMPDll,hICMP:THandle;
wsaData:TWSADATA;
ICMPCreateFile:TICMPCreateFile;
IcmpCloseHandle:TIcmpCloseHandle;
IcmpSendEcho:TIcmpSendEcho;
//destip: The remote address to be detected is as 192.168.1.1
PRocedure f_CheckOnline(destip:string);
var
IPOpt:TIPOptionInfo;// Package IP options
IPAddr:DWORD;
pReqData,pRevData:PChar;
pIPE:PIcmpEchoReply;// ICMP Echo Reply Buffer
FSize: DWORD;
MyString:string;
FTimeOut:DWORD;
BufferSize:DWORD;
i:integer;
Begin
hICMPdll := LoadLibrary('icmp.dll');//Click the icmp dynamic library
if hICMPDll<>NULL then
Begin
WSAStartup($101,wsaData);//Initialize the network protocol stack
@ICMPCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile');//Please the export function in the dynamic library
@IcmpCloseHandle := GetProcAddress(hICMPdll, 'IcmpCloseHandle');
@IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');
hICMP := IcmpCreateFile;//Create an icmp handle
IPAddr:= inet_addr(PChar(destip));//Get the IP address of the remote host to be detected
FSize := 40;
BufferSize := SizeOf(TICMPEchoReply) + FSize;
GetMem(pRevData,FSize);
GetMem(pIPE,BufferSize);
FillChar(pIPE^, SizeOf(pIPE^), 0);
pIPE^.Data := pRevData;
MyString := 'Hi, OnLine?';//Arbitrary string
pReqData := PChar(MyString);
FillChar(IPOpt, Sizeof(IPOpt), 0);
IPOpt.TTL := 64;
FTimeOut := 500;//Waiting time
i:=IcmpSendEcho(hICMP, IPAddr, pReqData, Length(MyString), @IPOpt, pIPE, BufferSize, FTimeOut);//If there is a return, the return value indicates the number of replies received. If 0 means no reply, the host cannot reach
FreeMem(pRevData);
FreeMem(pIPE);
IcmpCloseHandle(hicmp);
FreeLibrary(hICMPdll);//Release dynamic library
WSAcleanup();//Clean the protocol stack
end;
end;