有没有办法在PHP中做真正的ping? (没有执行)

时间:2013-10-03 16:23:02

标签: php ping icmp

我正在尝试使用ICMP数据包进行实际的正版ping,原生在PHP中。现在我正在使用exec来运行ping命令,但你永远不知道它将输出什么,这使得格式化web的结果非常困难。不同的网络设置可能会导致一些疯狂的输出。所以我使用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);
}

1 个答案:

答案 0 :(得分:1)

您可以更改您的sudoers文件,以允许www-data以root身份运行php脚本而无需密码。

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

然后你可以从你的apache php中exec(sudo /path/to/mypingscript),它会进行ICMP调用并返回一条符合你喜欢的格式的消息。

要注意,修改你的sudoers文件可能很危险。如果你打破它,你将无法运行sudo命令,如果你设置了错误的权限,这可能会带来严重的安全后果。