2

我正在尝试使用 ICMP 数据包在 PHP 中进行实际的、真正的 ping。现在我正在使用 exec 运行ping命令,但你永远不知道它会输出什么,这使得为 web.xml 格式化结果变得非常困难。不同的网络设置可能会导致一些疯狂的输出。因此,我使用 socket_create() 编写了自己的 pinger(在手动注释的帮助下),但这也不起作用。显然,除非您的 apache 服务器以 root 身份运行,否则您无法创建原始套接字。这也不是一个好的解决方案。

这是一个网络工具,访问者在其中运行 ping,这意味着他们访问了页面,我的服务器 ping 他们,并输出结果。所以我不能只打开一个 tcp 连接,关闭它,然后将其用作 ping,因为谁知道用户是否打开了任何端口。

还有一个用于 ping 的 pear 包,但最终它只是一个包装器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);
}
4

1 回答 1

1

您可以更改您的 sudoers 文件以允许 www-data 在没有密码的情况下以 root 身份运行 php 脚本。

www-data ALL=(ALL)NOPASSWD:/path/to/mypingscript

然后您可以exec(sudo /path/to/mypingscript)从您的 apache php 中进行 ICMP 调用并返回您喜欢的格式的消息。

但请注意,修改 sudoers 文件可能很危险。如果您破坏它,您将无法运行 sudo 命令,并且如果您设置错误的权限,这可能会产生不良的安全后果。

于 2013-10-04T08:45:48.520 回答