Cómo implementar PING con raw sockets (Delphi)

Windows admite un Protocolo de mensajes de control de Internet (ICMP) para determinar si un host determinado está disponible o no.  ICMP es un protocolo de capa de red que ofrece control de flujo, mensajes de error, enrutamiento y otros datos entre hosts de Internet. ICMP es usado principalmente por desarrolladores de aplicaciones para un ping de red.

 

¿Qué es un Ping?

Un ping es el proceso de enviar un mensaje de eco a una dirección IP y leer la respuesta para verificar una conexión entre hosts TCP/IP. Si está escribiendo una nueva aplicación, será mejor que utilice el soporte de raw sockets Winsock 2, implementado en Indy, por ejemplo.

Tenga en cuenta, sin embargo, que para las implementaciones de Windows NT y Windows 2000, los Raw Sockets están sujetos a comprobaciones de seguridad y sólo son accesibles para los miembros del grupo del administrador. Icmp.dll proporciona funcionalidad que permite a los desarrolladores escribir aplicaciones de ping de Internet en sistemas Windows sin soporte para Winsock 2.

Tenga en cuenta que la función Winsock 1.1 WSAStartup debe ser llamada antes de utilizar las funciones expuestas por ICMP.DLL. Si no lo hace, la primera llamada a IcmpSendEcho fallará con el error 10091 (WSASYSNOTREADY).

 

Abajo puedes encontrar el código fuente de la unidad Ping. Aquí hay dos ejemplos de uso.

 

Ejemplo 1: Code Snippet

uses Ping;...​const ADP_IP = '208.185.127.40'; (* http://delphi.about.com *)beginIf  Ping.Ping(ADP_IP) thenShowMessage('About Delphi Programming reachable!');end;

Ejemplo 2: Programa Delphi en modo consola

Nuestro siguiente ejemplo es el programa Delphi en modo consola que utiliza la unidad Ping: . Aquí está la fuente de la unidad Ping:

unit Ping;​interfaceusesWindows, SysUtils, Classes;typeTSunB = packed records_b1, s_b2, s_b3, s_b4: byte;end;TSunW = packed records_w1, s_w2: word;end;PIPAddr = ^TIPAddr;TIPAddr = recordcase integer of0: (S_un_b: TSunB);1: (S_un_w: TSunW);2: (S_addr: longword);end;IPAddr = TIPAddr;function IcmpCreateFile : THandle; stdcall; external 'icmp.dll';function IcmpCloseHandle (icmpHandle : THandle) : boolean;stdcall; external 'icmp.dll'function IcmpSendEcho(IcmpHandle : THandle; DestinationAddress : IPAddr;RequestData : Pointer; RequestSize : Smallint;RequestOptions : pointer;ReplyBuffer : Pointer;ReplySize : DWORD;Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll';function Ping(InetAddress : string) : boolean;implementationusesWinSock;function Fetch(var AInput: string;const ADelim: string = ' ';const ADelete: Boolean = true): string;variPos: Integer;beginif ADelim = #0 then begin// AnsiPos does not work with #0iPos := Pos(ADelim, AInput);end else beginiPos := Pos(ADelim, AInput);end;if iPos = 0 then beginResult := AInput;if ADelete then beginAInput := '';end;end else beginresult := Copy(AInput, 1, iPos - 1);if ADelete then beginDelete(AInput, 1, iPos + Length(ADelim) - 1);end;end;end;procedure TranslateStringToTInAddr(AIP: string; var AInAddr);varphe: PHostEnt;pac: PChar;GInitData: TWSAData;beginWSAStartup($101, GInitData);tryphe := GetHostByName(PChar(AIP));if Assigned(phe) thenbeginpac := phe^.h_addr_list^;if Assigned(pac) thenbeginwith TIPAddr(AInAddr).S_un_b do begins_b1 := Byte(pac[0]);s_b2 := Byte(pac[1]);s_b3 := Byte(pac[2]);s_b4 := Byte(pac[3]);end;endelsebeginraise Exception.Create('Error getting IP from HostName');end;endelsebeginraise Exception.Create('Error getting HostName');end;exceptFillChar(AInAddr, SizeOf(AInAddr), #0);end;WSACleanup;end;function Ping(InetAddress : string) : boolean;varHandle : THandle;InAddr : IPAddr;DW : DWORD;rep : array[1..128] of byte;beginresult := false;Handle := IcmpCreateFile;if Handle = INVALID_HANDLE_VALUE thenExit;TranslateStringToTInAddr(InetAddress, InAddr);DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);Result := (DW 0);IcmpCloseHandle(Handle);end;​end.

 

 

(0 votes)