Ayuda con PHP

BaGoroT

Hola a todos,tengo una duda sobre un PHP que tengo,está enlazado a un formulario HTML y lo que hace es enviar PINGS a los hosts que le indicas,el php funciona bien pero no logro entender realmente como está funcionando ya que el código no lo hice yo,este sería el trozo de código.(los datos son inventados).

if ($nombre == "host1"  ) {
 
$starttime = microtime(true);
$file      = @fsockopen ('192.168.90.211', 80, $errno, $errstr, 10); //Establecemos la conexión
$stoptime  = microtime(true);
$status    = 0;
 
if (!$file) $status = -1;  //Dispositivo caído
else {
}
 
if ($status <> -1) {
    echo '<center><h3>Ping a 192.168.90.211</h3> - <h1>Comunicación OK</h1></center>';
} else {
    echo '<center><h3>Ping a 192.168.90.211</h3> - <h1>Dispositivo caido</h1></center>';
 
   }
 }

El tema es que no entiendo como llega a realizar el PING,sé que fsockoopen abre una conexión durante 10s a la ip....El microtime muestra la hora actual en microsegundos pero no entiendo que hace ahí si ya el en parámetro de fsockopen le dices el tiempo de duración.
Después pone la variable status a 0, en el primer if entiendo que si el resultado booleano es -1 ¿ya es dispositivo caído?¿de donde sale ese -1 y que significa?
Perdonad mi ignorancia pero quiero entender este código.tampoco entiendo que significa ese -1 o si es distinto de -1 es es que hace ping.
Gracias mediavider0s.

B

Partiendo de la base de que el código es una puta mierda, te explico:

  • "stoptime" y "starttime" es un profiler para calcular cuando tiempo tarda en enviar la petición pero no se está usando por lo que lo puedes borrar.
  • Si la conexión es rechazada el código pone la variable en -1 para luego compararla de nuevo.

En resumen:

Si "fsockopen" devuelve falso muestra "dispositivo caido."

PD: Me debes 5 euros.

1
ciberares

http://php.net/manual/es/function.fsockopen.php
Valores devueltos

fsockopen() devuelve un puntero a fichero que puede ser utilizado junto a otras funciones de fichero (como fgets(), fgetss(), fwrite(), fclose(), y feof()). Si la llamada falla, devolverá FALSE.

Luego en

if (!$file) $status = -1; //Dispositivo caído
ve si efectivamente esta caido o no. Y si lo esta pone la variable status en -1

1
radykal

Básicamente ese código no hace PING como tal, simplemente abre un socket a la IP@puerto y en base a si puede o no establecer dicha comunicación da el OK o KO pero en absoluto envía el paquete ICMP contra la IP (que para PING no hay que especificar puerto, ya que ICMP es un protocolo distinto, sin puertos).
+1 a menuda basura de código que además no hace lo que dice

2
Chaflameja

Me encanta la llave a apertura y cierre del else sin contener nada

2
B

Esto es lo que ha traído StackOverflow.es

1
willy_chaos

En el código legacy de la web interna de mi empresa he visto varios else sin nada.

También encontrarme cosas como

If ( login.equals("") ) { login=""; }

Que dices.. El que lo hizo ese día estaba inspirado eeeehhh

1
BaGoroT

Gracias por las respuestas,comenté las líneas de MICROTIME y quité el echo vacío del código,conocéis como mejorar este código para realizar pings dentro de una red interna?,El código en general según comprobé cumple su función,me dice cuando el dispositivo está encendido o no,eso si,tengo problemas con algunos dispositivos creo que debido al firewall a los que no llega a realizar la conexión estando conectados...

Un saludo.

BaGoroT

Ahora sé que el código sale de esta función:

function pingDomain($domain){
    $starttime = microtime(true);
    $file      = @fsockopen ($domain, 80, $errno, $errstr, 10);
    $stoptime  = microtime(true);
    $status    = 0;
 
if (!$file) $status = -1; 
else {
    fclose($file);
    $status = ($stoptime - $starttime) * 1000;
    $status = floor($status);
}

if ($status <> -1) {
    echo 'Conectado';
} else {
    echo 'No conectado';
}

}
echo pingDomain("192.168.90.211");

¿Las opciones de MICROTIME son útiles dentro de una red interna?
¿Sabéis que hace en el primer "else"?

1 respuesta
cabron

#9

El primer else no tiene ningún sentido, podrías quitarlo y funcionaría igual

1 respuesta
MTX_Anubis

#10 hombre cierra el socket, tampoco está tan mal aunque imagino que se cerrará cuando finalice la ejecución del script, a mi personalmente me gusta cerrarlos :P

Es cierto que el resto no sirve ni para tomar por culo, de hecho podría resumirse en

if (!$file) echo 'No conectado';
else echo 'Conectado';
1 respuesta
Traber

El problema que tienes con esa forma de hacer ping es que estás confundiendo lo que es un ping mediante ICMP que abrir una conexión mediante un socket al puerto 80 de una máquina.

Te resumo más o menos las condiciones que debe reunir una máquina para poder recibir ping según el método:

  • ICMP: El firewall debe permitir tráfico ICMP.
  • Puerto XX: El firewall debe permitir el tráfico entrante en el puerto XX, y detrás debe haber un servicio respondiendo a las conexiones entrantes.

El ICMP es el tipo de tráfico que se utiliza para medir el ping REAL, mientras que el método de abrir un socket a un puerto sirve para medir el tiempo de respuesta DE UN SERVICIO, con lo cual, si no hay un servicio detrás, NO HAY PING.

El tuyo es el segundo caso, si las máquinas a las que hagas ping no tienen detrás un servicio HTTP no te van a responder, no va a poder realizar la conexión, y esa función te va a devolver siempre -1, aunque sí puedas acceder a dicha máquina.

Voy a intentar explicar más o menos lo que hace el código:

$starttime = microtime(true); # Toma nota de la hora de inicio del script para medición del ping
$file      = @fsockopen ($domain, 80, $errno, $errstr, 10); # Abre un socket en el puerto 80 de la máquina objetivo
$stoptime  = microtime(true); # Toma nota de la hora de fin del script para medición del ping
$status    = 0; #Inicialización de la variable status (aunque podría haber sido FALSE directamente

Seguimos para bingo

if (!$file) $status = -1; # Si no ha podido abrir el socket, el resultado de fsockopen es "false". Si ocurre esto, significa que no se puede conectar con el servidor, y seteamos la variable a -1.
else { # Se ha podido abrir el socket
    fclose($file); # Cerramos el socket
    $status = ($stoptime - $starttime) * 1000; # Calculamos en milisegundos el ping
    $status = floor($status); # Redondeamos el ping para evitar cosas como 5.99999999999ms en lugar de 6ms o 5.99ms
}

Que es un código muy básico, no me jodas xD. Si ese código lo ejecutas desde un servidor propio o como script de línea de comandos, si lo ejecutas como administrador puedes utilizar esto: https://github.com/geerlingguy/Ping

Por último, cómo dejaría yo el código:

function pingDomain($domain, $port = 80){
    $starttime = microtime(true);
    $file      = @fsockopen ($domain, $port, $errno, $errstr, 10);
    $stoptime  = microtime(true);
    $status    = FALSE;

    if($file){
        fclose($file);
        $status = ($stoptime - $starttime) * 1000;
        $status = floor($status);
    }
    return $status;
}

$domain_ping = pingDomain("192.168.90.211");
if ($domain_ping !== FALSE) {
    echo 'Conectado | Ping: ' . $domain_ping . 'ms';
} else {
    echo 'No conectado';
}
2 respuestas
cabron

#11

Se cierra solo al terminar la función sí, por eso no afectaría quitarlo entero, aunque tampoco hace daño cerrarlo de forma explícita

#12

La parte de medir el tiempo la puedes quitar por que no usa nunca el tiempo para nada, solo mira si se ha podido conectar o no

1 respuesta
Traber

#13 En mi script sí lo uso (que para algo haces ping), por eso lo he puesto:

echo 'Conectado | Ping: ' . $status . 'ms';

Es más, voy a corregirlo y ponerlo de otra forma xD.

1 respuesta
cabron

#14

Ah no me había fijado, yo lo decía por lo que hacía la función original, es más que coño, la función original se puede hacer en una línea:

echo @fsockopen ($domain, 80, $errno, $errstr, 10) ? 'Conectado' :  'No conectado' ;
BaGoroT

#12
Muchísimas gracias,esto me va mejor.

10 días después
BaGoroT

Rescato el hilo para haceros otra consulta, tengo un problema con las PDA a las que quiero enviar el socket, estas no contestan, llevan Windows Mobile 6.1 y no consigo encontrar la forma de aceptar el tráfico en el puerto x, en el manual tampoco encontré nada.¿Tenéis experiencia con este S.O para conseguir enviarles el socket desde el PHP?.
Un saludo.

Usuarios habituales