Function HB_PING

Post Reply
User avatar
acuellar
Posts: 1713
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Function HB_PING

Post by acuellar »

Estimado Antonio

Es posible incluir la función HB_PING en las LIBs de la nueva versión de FWH

HB_PING.PRG

Code: Select all | Expand

#pragma BEGINDUMP
#include <hbapi.h> 
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>

int hb_Ping( const char * cp )
{
    HANDLE hIcmpFile;
    unsigned long ipaddr;
    DWORD dwRetVal;
    char SendData[32] = "Data Buffer";
    LPVOID ReplyBuffer;
    DWORD ReplySize;

ipaddr = inet_addr( cp );
if (ipaddr == INADDR_NONE)
    return 1;

hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE)
    return 2;

ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL)
    return 3;

dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData), 
    NULL, ReplyBuffer, ReplySize, 1000);

if (dwRetVal == 0)
    return 4;

return 0;
}

HB_FUNC( HB_PING )
{
   hb_retni( hb_Ping( hb_parc( 1 ) ) );
}
#pragma ENDDUMP
 

Muchas gracias de antemano

Saludos,

Adhemar Cuéllar

User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Function HB_PING

Post by Antonio Linares »

Estimado Adhemar,

Función añadida a FWH, muchas gracias :wink: :!:

* New: function HB_PING( cIP ) --> nResult. Ejemplo de uso:

Code: Select all | Expand

FUNCTION Main()
    LOCAL nResultado
    LOCAL cIP := "8.8.8.8" // Servidor DNS de Google

// Llamada correcta
nResultado := HB_PING( cIP )

IF nResultado == 0
   ? "Ping exitoso a " + cIP
ELSE
   ? "Error al hacer ping. Código:", nResultado
ENDIF
  RETURN NIL

Valor Significado Causa en el código C
0 Exito El ping respondió correctamente (dwRetVal != 0).
1 Error de IP El formato de la IP es inválido o se pasó un nombre de dominio (inet_addr falló).
2 Error de Handle No se pudo abrir el archivo ICMP (IcmpCreateFile falló).
3 Error de Memoria No se pudo asignar memoria para la respuesta (malloc falló).
4 Fallo / Timeout Se envió el ping pero no hubo respuesta o hubo error en el envío (dwRetVal == 0).

Gracias a Adhemar Cuellar: viewtopic.php?p=283090#p283090

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Jimmy
Posts: 1799
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: Function HB_PING

Post by Jimmy »

hi,

i have try it and got

HB_PING.prg(33): warning C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings

  • Application successfully built *

App was build and run, but how to fix the Warning ?

greeting,
Jimmy
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Function HB_PING

Post by Antonio Linares »

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <hbapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>

regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: Function HB_PING

Post by Antonio Linares »

Modificamos la función para que acepte dominios que se convierten a IPs:

Code: Select all | Expand

#pragma BEGINDUMP
#include <hbapi.h> 
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>

// Nota: Asegúrate de enlazar con las librerías: ws2_32.lib e iphlpapi.lib

int hb_Ping( const char * cp )
{
    HANDLE hIcmpFile;
    unsigned long ipaddr;
    DWORD dwRetVal;
    char SendData[32] = "Data Buffer";
    LPVOID ReplyBuffer;
    DWORD ReplySize;
    
// Estructuras para manejo de DNS WSADATA wsaData; struct hostent *host; // 1. Inicializar Winsock (Requerido para gethostbyname) if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return 5; // Error: No se pudo iniciar Winsock // 2. Intentar convertir cadena IP numérica directa ipaddr = inet_addr( cp ); // 3. Si no es numérica, intentar resolver como dominio (DNS) if (ipaddr == INADDR_NONE) { host = gethostbyname( cp ); if ( host == NULL ) { WSACleanup(); return 1; // Error: Nombre de dominio no válido o no encontrado } ipaddr = *(unsigned long *) host->h_addr_list[0]; } hIcmpFile = IcmpCreateFile(); if (hIcmpFile == INVALID_HANDLE_VALUE) { WSACleanup(); return 2; } ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); ReplyBuffer = (VOID*) malloc(ReplySize); if (ReplyBuffer == NULL) { IcmpCloseHandle(hIcmpFile); // Cerrar handle antes de salir WSACleanup(); return 3; } dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000); // 1000ms de timeout // Limpieza de recursos free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); WSACleanup(); if (dwRetVal == 0) return 4; // Ping fallido (Timeout o red inalcanzable) return 0; // Éxito } HB_FUNC( HB_PING ) { hb_retni( hb_Ping( hb_parc( 1 ) ) ); } #pragma ENDDUMP

Cambios Clave Realizados
WSAStartup: Para usar funciones de DNS (nombres de dominio), Windows requiere que se inicie el subsistema de sockets primero. Si esto falla, devuelve el nuevo error 5.

gethostbyname: Si inet_addr dice que no es una IP numérica (ej. recibes "microsoft.com"), el código ahora entra en el if y pregunta al sistema por la IP de ese nombre.

WSACleanup: Es muy importante liberar los recursos de sockets antes de que la función termine (he agregado estas llamadas antes de cada return).

Limpieza de Memoria: Agregué free(ReplyBuffer) y IcmpCloseHandle antes de salir para evitar fugas de memoria si usas esta función muchas veces seguidas.

Code: Select all | Expand

// 1. Funciona con IPs
nRes := HB_PING( "8.8.8.8" ) 

// 2. Funciona con Dominios
nRes := HB_PING( "google.com" )
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
acuellar
Posts: 1713
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Function HB_PING

Post by acuellar »

Excelente

Muchas gracias Estimado Antonio

Saludos,

Adhemar Cuéllar

Post Reply