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

发布于 2024-10-11 14:55:26 字数 250 浏览 6 评论 0原文

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

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

我也想使用 fsockopen() 尝试在指定端口上进行连接,但如果主机没有侦听该端口上的连接,那么也会失败。

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

I'm trying to do this in PHP. I need to check if a specified host is "up"

I thought of pinging the specified host (though I'm not sure how I would, since that would require root. --help here?)

I also though of using fsockopen() to try to connect on a specified port, but that would fail too, if the host wasn't listening for connections on that port.

Additionally, some hosts block ping requests, so how might I get around this? This part isn't a necessity, though, so don't worry about this too much. I realize this one might get tricky.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

離人涙 2024-10-18 14:55:26

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

I typically do a simple cURL for a public page and see if it returns a 200. If you get a 500, 404, or anything besides a 200 response you know something fishy is up.

め可乐爱微笑 2024-10-18 14:55:26

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

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

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

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

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

The short answer is that there is no good, universal way to do this. Ping is about as close as you can get (almost all hosts will respond to that), but as you observed, in PHP that usually requires root access to use the low port.

Does your host allow you to execute system calls, so you could run the ping command at the OS level and then parse the results? This is probably your best bet.

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

If a host is blocking a ping request, you could do a more general portscan to look for other open ports (but this is pretty rude, don't do it to hosts who haven't given you specific permission). Nmap is a good tool for doing this. It uses quite a few tricks to figure out if a host is up and what services may or may not be running. Be careful though, as some shared hosting providers will terminate your account for "hacking activity" if you install and use Nmap, especially against hosts you do not control or have permission to probe.

Beyond that, if you are on the same unswitched ethernet layer as another host (if you happen to be on the same open WiFi network, for example), an ethernet adaptor in promiscuous mode can sniff traffic to and from a host even if it does not respond directly to you.

雨后咖啡店 2024-10-18 14:55:26

你可以使用 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
}

You could use 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
}
梨涡 2024-10-18 14:55:26

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

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

编辑——

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

编辑--

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

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

For the host to be monitored at all, at least one port must be open. Is the host a web server? If so you could just open a connection to port 80, as long as it's opened successfully then at least some part of the host is working.

A better solution would be to have a script that is web accessible to just your monitor, and then you could open a connection to that, and that script would return various bits of system info.

EDIT--

How thorough do you want this test to be?
[server on] -> [apache running] -> [web application working]
Are all different levels of working. Just showing apache is returning something does at least show the server is on, but not that your web app is running.
(I realise that you may not be running anything like this but I hope it's a useful example)

EDIT--

Would it be worth installing a lightweight http server (I mean very light weight) just for monitoring?

Failing that could you install something on the hosts that phoned home every so often to show they are up?

世态炎凉 2024-10-18 14:55:26

没有通用的方法来检查它,但对于大多数情况,ping 都可以。

某些提议的问题

  • exec 可能在某些共享主机中不可用,并且作为高级第三方功能,它很慢,并且依赖于操作系统的
  • curl 和基于 HTTP 的方法将起作用仅当主机在端口 80 上提供 HTTP 服务时,情况可能并非如此(我用它来检查本地计算机的 Samba 连接)

当您可能期望错误结果时?

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

  • 您计算机的防火墙或网络设置禁止发送 ping(但是 exec('ping... 不会有帮助))
  • 您的 PHP 安装缺少 Sockets 扩展这也是这种方式最大的缺点
  • 机器应答太慢(可以通过调整 $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 秒

表示“无超时”(等待时间为 1 秒) 。至少这是我的实验所表明的,但我在 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 线上产生警告,从而使 静音。 @ 符号。

There's no universal way to check it, but for most cases ping would work.

The problems with some proposals

  • exec might be not available in some shared hostings and as high level, third party function, it's slow and OS-depended
  • curl and HTTP based methods will work only if there's host with HTTP service on port 80, which might be not the case (I use it to check local machines for Samba connectivity)

When you may expect wrong results?

As I said, it will work in most cases, but it's not a silver bullet. You can do something with the first three cases, but not with the last.

  • your machine's firewall or network settings forbids sending pings (but then exec('ping… won't help)
  • your PHP installation is missing Sockets extension (which is also the biggest drawback of this way)
  • machine answer's too slow (which can be changed by tweaking $msTimeout parameter)
  • remote machine blocks all ICMP traffic (or just pings)

The code

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

Usage/explanation

The usage is very simple, this function returns boolean value for given hostname or IP (as string), while the second parameter (integer) is optional and sets timeout in miliseconds. Default is 1000 ms, which is 1 s.

0 timeout means "no timeout" (wait as long as it's needed). At least that's what my experiments show, but I don't see it in PHP docs, so I wouldn't rely on that.

Example use:

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

It works by pinging the machine, but unlike typical ping it doesn't check how quick the reply is, but if there's reply at all. If the machine is unreachable, it would produce warning on the line with socket_read, hence the silencing @ symbol.

记忆消瘦 2024-10-18 14:55:26

我使用了gethostbyname($hostname)

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

if ($hostname !== gethostbyname($hostname)) {
    //Host is up
}

I used gethostbyname($hostname).

The function gives you the IP if the host is up, or the input hostname if it couldn't find the IP.

if ($hostname !== gethostbyname($hostname)) {
    //Host is up
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文