PHP中fsockopen的非阻塞替代品?

时间:2019-06-10 15:54:40

标签: php codeigniter sockets

我已经阅读了很多答案,但没有找到明确的解释。我正在尝试使用PHP创建开放端口检查工具。

使用fsockopen时,服务器在检查每个端口时停止工作,因此我无法使用此方法检查端口状态。

除了以非阻塞或异步方式之外,是否有任何有效的方法可以完成相同的工作?

这是我的(无效)代码:

        $resultList = [];
        foreach ($list as $key => $value) {
             $object = new stdClass();
             $object->id = $value["id"];

            if (fsockopen($value["ip"], $value["port"])) {
                 $object->status = true;
            } else {
                $object->status = false;
            }
            array_push($resultList,$object);
        }

1 个答案:

答案 0 :(得分:0)

PHP脚本始终是同步的-您调用一个函数,等待脚本完成后再继续运行,但是您可以通过以下通用命令使用PHP触发另一个PHP脚本作为新进程:

shell_exec('/usr/bin/php -f /path/to/script.php &> /dev/null &');

现在这并不能真正解决您的问题,我只是将其包含在内以回答您所问问题的确切内容-您不能在不涉及AJAX的情况下使第二个PHP脚本与第一个PHP脚本进行任何交互。以及整个过程都是AJAX。


要尝试回答您的问题的精神,我想提出另一种方法:

您拥有父页面:

<?php

$hostname = '192.168.0.1';

?>
<h1>Ports for server <?php echo $hostname; ?>:</h1>
<iframe src="/path/to/my/post-scanner-script.php?hostname=<?php echo urlencode($hostname); ?>"></iframe>

然后,您的子页面会依次扫描每个端口,并在完成扫描该端口后使用flush()

<?php

// Stuff here to interpret $_GET['hostname'];

foreach ($list as $key => $value) {
    $status = !!fsockopen($value["ip"], $value["port"]);
    echo "<div>{$value['id']}: " . ($status ? 'OPEN' : 'CLOSED') . "</div>";
    flush();
}

flush()要做的是立即将所有渲染的输出发送到客户端计算机(它将不会两次发送相同的内容),因此您将得到的是每个端口及其状态的缓慢出现的列表,一旦您的脚本知道端口的状态。

这为最终用户提供了一些立即的反馈信息,并减少了令人沮丧的等待时间(当您可以实际看到正在取得的进展时,这是可以忍受的。)