【发布时间】:2013-10-10 10:50:10
【问题描述】:
我正在尝试使用 ICMP 数据包在 PHP 中进行实际的、真正的 ping。现在我正在使用 exec 运行 ping 命令,但你永远不知道它会输出什么,这使得为 web.xml 格式化结果变得非常困难。不同的网络设置可能会导致一些疯狂的输出。因此,我使用 socket_create() (在手动 cmets 的帮助下)编写了自己的 pinger,但这也不起作用。显然,除非您的 apache 服务器以 root 身份运行,否则您无法创建原始套接字。这也不是一个好的解决方案。
这是一个网络工具,访问者可以在其中对自己运行 ping,这意味着他们访问了该页面,我的服务器会 ping 他们并输出结果。所以我不能只打开一个 tcp 连接,然后关闭它,然后将其用作 ping,因为谁知道用户是否打开了任何端口。
还有一个pear包用于ping,但最终它只是exec("ping $host");的包装器
我可能会被我使用系统 ping 命令的旧代码卡住。但我只想先确定没有其他解决方案。因为如果可以的话,我真的想在 PHP 中原生地做到这一点。
这是我的 ping 功能。它失败并出现“无法创建套接字 [1]”错误:
function ping_you()
{
$package = "\x08\x00\x19\x2f\x00\x00\x00\x00\x70\x69\x6e\x67";
$sock = socket_create(AF_INET, SOCK_RAW, 1);
if ($sock === false)
{
echo ">> " . socket_strerror(socket_last_error()) . " <<";
}
socket_bind($sock,OPERATING_IP);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 1, "usec" => 0));
socket_connect($sock, $_SERVER['REMOTE_ADDR'], null);
$start_time = microtime(true);
socket_send($sock, $package, strlen($package), 0);
if(@socket_read($sock, 255))
{
$end_time = microtime(true);
return $end_time - $start_time;
}
else
{
return false;
}
socket_close($sock);
}
【问题讨论】:
-
如何使用 CURL 进行 ping 操作?
-
你必须是 root 才能创建原始套接字。
-
是的...这就是我这么说的原因。
-
所以你知道作为 not-root 这样做是不可能的,对吧?
-
那么也许您可以更改您的 sudoers 文件以允许 www-data 在没有密码的情况下以 root 身份运行 php 脚本。然后你可以
exec这个脚本,它会进行ICMP调用并返回一个格式化为你喜欢的消息。