有办法检查主机是否启动吗?

问题描述 投票:0回答:6

我正在尝试用 PHP 来做到这一点。我需要检查指定主机是否“启动”

我想 ping 指定的主机(尽管我不确定如何执行,因为这需要 root。--这里有帮助吗?)

我还尝试使用

fsockopen()
尝试连接指定端口,但如果主机没有侦听该端口上的连接,这也会失败。

此外,某些主机会阻止 ping 请求,那么我该如何解决这个问题呢?不过,这部分不是必需的,所以不必太担心。我意识到这可能会变得棘手。

php ping fsockopen
6个回答
5
投票

我通常会对公共页面执行一个简单的 cURL,看看它是否返回 200。如果您得到 500、404 或除 200 之外的任何响应,您就知道有问题了。


4
投票

简单的回答是,没有好的、通用的方法可以做到这一点。 Ping 大约是您能得到的最接近的结果(几乎所有主机都会响应),但正如您所观察到的,在 PHP 中通常需要 root 访问权限才能使用低端口。

您的主机是否允许您执行系统调用,以便您可以在操作系统级别运行 ping 命令,然后解析结果?这可能是您最好的选择。

$result = exec("ping -c 2 google.com");

如果主机阻止 ping 请求,您可以执行更通用的端口扫描来查找其他开放端口(但这非常粗鲁,不要对未授予您特定权限的主机执行此操作)。 Nmap 是执行此操作的好工具。它使用了很多技巧来确定主机是否已启动以及哪些服务可能正在运行或可能没有运行。但要小心,因为如果您安装和使用 Nmap,一些共享托管提供商会因“黑客活动”而终止您的帐户,特别是针对您无法控制或无权探测的主机。

除此之外,如果您与另一台主机位于同一非交换以太网层(例如,如果您碰巧位于同一个开放 WiFi 网络上),处于混杂模式的以太网适配器可以嗅探进出主机的流量,即使它不直接回复你。


1
投票
你可以使用 cURL

$url = 'yoururl'; $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_exec($ch); $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (200==$retcode) { // All's well } else { // not so much }
    

0
投票
对于要监控的主机,至少必须打开一个端口。主机是网络服务器吗?如果是这样,你可以打开一个到端口 80 的连接,只要它成功打开,那么至少主机的某些部分正在工作。

更好的解决方案是拥有一个仅可由您的显示器通过网络访问的脚本,然后您可以打开到该脚本的连接,该脚本将返回各种系统信息。

编辑--

您希望这次测试有多彻底? [服务器开启] -> [apache 运行] -> [Web 应用程序工作] 都是不同级别的工作。仅显示 apache 正在返回某些内容至少可以显示服务器已打开,但不能表明您的 Web 应用程序正在运行。 (我意识到你可能没有运行这样的东西,但我希望这是一个有用的例子)

编辑--

是否值得安装一个轻量级http服务器(我的意思是非常轻量)只是为了监控?

如果做不到这一点,您可以在经常打电话回家以显示其已启动的主机上安装一些东西吗?


0
投票
没有通用的方法来检查它,但对于

大多数情况,ping 可以工作。

一些提案的问题

  • exec
     在某些共享主机中可能不可用,并且作为高级第三方功能,它很慢且取决于操作系统
  • curl
     和基于 HTTP 的方法仅在端口 80 上有具有 HTTP 服务的主机时才有效,但情况可能并非如此(我用它来检查本地计算机的 Samba 连接)
什么时候你可能会得到错误的结果?

正如我所说,它在大多数情况下都有效,但这不是灵丹妙药。你可以对前三种情况做一些事情,但不能对最后一种情况做一些事情。

    您机器的防火墙或网络设置禁止发送 ping(但
  • exec('ping…
    无济于事)
  • 你的PHP安装丢失了
  • Sockets extension
    这也是这种方式最大的缺点
  • 机器回答太慢(可以通过调整 $msTimeout 参数来更改)
  • 远程计算机阻止所有 ICMP 流量(或仅 ping)
代码

function isHostUp($host, $msTimeout = 1000) { $socket = socket_create(AF_INET, SOCK_RAW, 1); socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 0, 'usec' => 1000 * $msTimeout)); socket_connect($socket, $host, null); socket_send($socket, "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost", 16, 0); $result = (bool)@socket_read($socket, 255); socket_close($socket); return $result; }
使用/说明

用法非常简单,该函数返回给定主机名或IP(作为字符串)的布尔值,而第二个参数(整数)是可选的,并以毫秒为单位设置超时。默认为 1000 毫秒,即 1 秒。

0超时表示“无超时”(只要需要就等待)。至少我的实验表明了这一点,但我在 PHP 文档中没有看到它,所以我不会依赖它。

使用示例:

isHostUp('1.1.1.1'); // simply check if 1.1.1.1 is reachable isHostUp('example.com', 5000); // check if example.com is up and wait at most 5 seconds for reply
它的工作原理是 ping 机器,但与典型的 ping 不同,它不会检查回复的速度,而是检查是否有回复。如果机器无法访问,它

socket_read

线上产生警告,因此出现静音
@
符号。


-2
投票
我用过

gethostbyname($hostname)

如果主机已启动,该函数会为您提供 IP;如果找不到 IP,则该函数会为您提供输入主机名。

if ($hostname !== gethostbyname($hostname)) { //Host is up }
    
© www.soinside.com 2019 - 2024. All rights reserved.