如何使用PHP ping服务器端口?

时间:2012-03-23 15:09:57

标签: php ping

我想要一个PHP脚本,它允许您ping IP地址和端口号(ip:port)。我发现了一个类似的脚本,但它仅适用于网站,而不适用于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);

?>

我希望将其用于游戏服务器。

我的想法是我可以输入IP地址和端口号,然后收到ping响应。

9 个答案:

答案 0 :(得分:66)

我认为this question的答案几乎总结了你问题的问题。

  

如果您想要做的是确定给定的主机是否会接受   端口80上的TCP连接,您可以这样做:

$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);
     

除了TCP之外的任何事情都会更加困难(尽管如此)   你指定80,我猜你正在寻找一个活跃的HTTP服务器,所以   TCP就是你想要的)。 TCP已按顺序排列并确认,因此您将这样做   在连接成功时隐式接收返回的数据包   制作。大多数其他传输协议(通常是UDP,但其他传输协议   好)不要以这种方式行事,数据报也不会   除非覆盖的应用层协议,否则确认   实现它。

     

你以这种方式问这个问题的事实告诉我你   您对Transport Layer协议的知识存在根本差距。   您应该阅读ICMPTCP以及OSI Model

此外,还有一个slightly cleaner版本可以ping到主机。

// 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;
}

答案 1 :(得分:18)

如果OP真的需要ICMP-Ping,那么使用原始套接字的socket_create() [link]的用户贡献注释中有一些提议。请注意,在类似UNIX的系统上,需要root访问权限。

更新:请注意usec参数在Windows上没有任何功能。最短超时为1秒。

无论如何,这是最高投票ping功能的代码:

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;
}

答案 2 :(得分:3)

试试这个:

echo exec('ping -n 1 -w 1 72.10.169.28');

答案 3 :(得分:2)

你不需要任何exec或shell_exec黑客来做到这一点,它可以在PHP中完成。 “你想用PHP做什么?”凯文施罗德,秀是如何。

它使用套接字和pack()函数,它允许您读取和写入二进制协议。您需要做的是创建一个ICMP数据包,您可以使用“CCnnnA *”格式创建数据包。

答案 4 :(得分:2)

测试不同的端口:

$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

答案 5 :(得分:2)

function ping($ip){
    $output = shell_exec("ping $ip");
    var_dump($output);
}
ping('127.0.0.1');

更新: 如果您传递硬编码的IP(如本示例和大多数实际情况),此功能就足够了。

但由于某些用户似乎非常关注安全性,请提醒从不将用户生成的输入传递给shell_exec函数: 如果IP来自不受信任的来源,请至少在使用之前检查with a filter

答案 6 :(得分:0)

socket_create需要在具有;

的UNIX系统上以root用户身份运行
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);

答案 7 :(得分:0)

如果你想在php中发送ICMP数据包,你可以看看这个Native-PHP ICMP ping implementation,但我没有测试它。

答案 8 :(得分:-1)

您可以使用exec功能

 exec("ping ".$ip);

here一个例子