web-dev-qa-db-fra.com

Comment puis-je envoyer une requête ping à un port de serveur avec PHP?

Je veux un script PHP qui vous permet d'envoyer une requête ping à une adresse IP et à un numéro de port (ip:port). J'ai trouvé un script similaire, mais il ne fonctionne que pour les sites Web, pas ip:port.

<?php

function ping($Host, $port, $timeout) 
{ 
  $tB = microtime(true); 
  $fP = fSockOpen($Host, $port, $errno, $errstr, $timeout); 
  if (!$fP) { return "down"; } 
  $tA = microtime(true); 
  return round((($tA - $tB) * 1000), 0)." ms"; 
}

//Echoing it will display the ping if the Host is up, if not it'll say "down".
echo ping("www.google.com", 80, 10);

?>

Je veux ceci pour un serveur de jeu.

L'idée est que je peux taper l'adresse IP et le numéro de port et obtenir la réponse au ping.

39
user1288533

Je pense que la réponse à cette question résume assez bien le problème de votre question.

Si vous voulez savoir si un hôte donné acceptera TCP sur le port 80, vous pouvez le faire:

$Host = '193.33.186.70'; 
$port = 80; 
$waitTimeoutInSeconds = 1; 
if($fp = fsockopen($Host,$port,$errCode,$errStr,$waitTimeoutInSeconds)){   
   // It worked 
} else {
   // It didn't work 
} 
fclose($fp);

Pour tout autre chose que TCP, ce sera plus difficile (bien que puisque Vous spécifiez 80, je suppose que vous recherchez un serveur HTTP actif, donc TCP est ce que vous voulez). TCP est séquencé et reconnu, vous ferez donc recevoir implicitement un paquet retourné lorsqu'une connexion est établie avec succès fabriqué. La plupart des autres protocoles de transport (généralement UDP, mais d'autres comme Bien) ne se comportent pas de cette manière et les datagrammes ne le seront pas acquitté sauf si le protocole de couche d'application superposé le met en œuvre.

Le fait que vous posiez cette question de cette manière me dit que vous avoir une lacune fondamentale dans vos connaissances sur les couches de transport protocoles . Vous devriez lire les informations sur ICMP et TCP , ainsi que sur le modèle OSI .

En outre, voici une version légèrement plus propre pour envoyer une requête ping aux hôtes.

// Function to check response time
function pingDomain($domain){
    $starttime = microtime(true);
    $file      = fsockopen ($domain, 80, $errno, $errstr, 10);
    $stoptime  = microtime(true);
    $status    = 0;

    if (!$file) $status = -1;  // Site is down
    else {
        fclose($file);
        $status = ($stoptime - $starttime) * 1000;
        $status = floor($status);
    }
    return $status;
}
65
ShadowScripter

Dans le cas où l'OP souhaitait réellement un ICMP-Ping, il existe quelques propositions dans les notes contribuées par l'utilisateur à socket_create()[lien] , qui utilisent des sockets brutes. Sachez que sous UNIX, un accès root est requis pour les systèmes.

Mise à jour: notez que l'argument usec n'a aucune fonction sur Windows. Le délai d'attente minimum est de 1 seconde.

Dans tous les cas, il s'agit du code de la fonction ping la plus votée:

function ping($Host, $timeout = 1) {
    /* ICMP ping packet with a pre-calculated checksum */
    $package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
    $socket  = socket_create(AF_INET, SOCK_RAW, 1);
    socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
    socket_connect($socket, $Host, null);
    $ts = microtime(true);
    socket_send($socket, $package, strLen($package), 0);
    if (socket_read($socket, 255)) {
        $result = microtime(true) - $ts;
    } else {
        $result = false;
    }
    socket_close($socket);
    return $result;
}
17
user1931751

Essaye ça :

echo exec('ping -n 1 -w 1 72.10.169.28');
4
David Bélanger

Testez différents ports:

$wait = 1; // wait Timeout In Seconds
$Host = 'example.com';
$ports = [
    'http'  => 80,
    'https' => 443,
    'ftp'   => 21,
];

foreach ($ports as $key => $port) {
    $fp = @fsockopen($Host, $port, $errCode, $errStr, $wait);
    echo "Ping $Host:$port ($key) ==> ";
    if ($fp) {
        echo 'SUCCESS';
        fclose($fp);
    } else {
        echo "ERROR: $errCode - $errStr";
    }
    echo PHP_EOL;
}


// Ping example.com:80 (http) ==> SUCCESS
// Ping example.com:443 (https) ==> SUCCESS
// Ping example.com:21 (ftp) ==> ERROR: 110 - Connection timed out
2
Geo
function ping($ip){
    $output = Shell_exec("ping $ip");
    var_dump($output);
}
ping('127.0.0.1');

UPDATE: Si vous transmettez une adresse IP codée en dur (comme dans cet exemple et la plupart des scénarios de cas réels), cette fonction peut suffire. 

Mais comme certains utilisateurs semblent très préoccupés par la sécurité, rappelez-vous de ne jamais transmettre les entrées générées par l'utilisateur à la fonction Shell_exec: Si l'adresse IP provient d'une source non approuvée, vérifiez-la au moins avec un filtre avant de l'utiliser.

2
T30

Vous n'avez besoin d'aucun hacks exec ou Shell_exec, il est possible de le faire en PHP. Le livre 'Vous voulez faire QUOI avec PHP?' par Kevin Schroeder, le show est comment.

Il utilise des sockets et la fonction pack() qui vous permet de lire et d’écrire des protocoles binaires. Ce que vous devez faire est de créer un paquet ICMP, ce que vous pouvez faire en utilisant le format "CCnnnA *" pour créer votre paquet.

2
markus

Si vous voulez envoyer des paquets ICMP en PHP, vous pouvez jeter un oeil à cette implémentation de ping ICMP Native-PHP ICMP , mais je ne l'ai pas testée.

0
jcubic

socket_create doit être exécuté en tant que root sur un système UNIX avec;

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
0
PodTech.io