类似SSH的php套接字服务器

类似SSH的php套接字服务器,php,sockets,Php,Sockets,我有一个CLI php脚本,用于收集用户输入、处理它并返回基于它的信息。目前,只有通过SSH连接到PHP所在的服务器并运行phpscriptname.PHP,才能使用它,但是,我知道PHP可以创建套接字服务器。有没有可能,如果有,如何创建一个套接字服务器来侦听连接,并且在用户连接后,为脚本提供一个类似终端的环境,直到用户断开连接为止?对于每个连接的用户,它也将是一个不同的脚本实例。不需要身份验证 编辑:如果PHP无法做到这一点,还有什么其他选项 编辑: 下面是我使用的一些代码 用于收集用户输入:

我有一个CLI php脚本,用于收集用户输入、处理它并返回基于它的信息。目前,只有通过SSH连接到PHP所在的服务器并运行
phpscriptname.PHP
,才能使用它,但是,我知道PHP可以创建套接字服务器。有没有可能,如果有,如何创建一个套接字服务器来侦听连接,并且在用户连接后,为脚本提供一个类似终端的环境,直到用户断开连接为止?对于每个连接的用户,它也将是一个不同的脚本实例。不需要身份验证

编辑:如果PHP无法做到这一点,还有什么其他选项

编辑: 下面是我使用的一些代码

用于收集用户输入:

  echo "Enter a command or question... \n";
  $line = $this->input();
  $line = trim($line);
这将调用input函数,该函数将使用readline获取用户输入并返回它,然后脚本解释输入并基于它生成响应,然后请求更多输入。除非您告诉它,否则这个脚本不会结束。我希望能够通过PHP套接字服务器或类似服务器连接到它,这样我就可以在不使用SSH的情况下发送命令

编辑:
因此,我尝试了
xinetd
服务器,我可以连接到它,但是readline和许多其他东西,包括通过SSH访问时使用的格式,在telnet中不再有效。是否有其他方法可以做到这一点,或者有其他方法可以将其配置为更灵活的格式和读线格式?

当然有可能。您不需要Apache Web服务器或类似的东西。我的意思是,您可以使用这些东西,但最简单的方法是编写一个PHP脚本并让它在某个端口上进行侦听。要么调整脚本,要么编写另一个脚本,在套接字和脚本之间传输stdio。通常,如果您是用C编写的,那么无论您使用什么系统C libs或POSIX libs,都会有PHP包装器。在您的情况下,您可能希望使用。这本书中有许多例子

为了给出jist,这是一个简单的PHP echo服务器——它只打印回您键入的任何内容。我记不起这是从哪里来的,很抱歉没有态度:

error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. Only applies to httpd module. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting as it comes in. Only applies to httpd module.*/
ob_implicit_flush();

$address = '127.0.0.1';
$port = 10000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}
if (socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
if (socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
}
do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    /* Send instructions. */
    $msg = "\nWelcome to the PHP Test Server. \n" .
        "To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
    socket_write($msgsock, $msg, strlen($msg));
    do {
        if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
            echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
            break 2;
        }
        if (!$buf = trim($buf)) {
            continue;
        }
        if ($buf == 'quit') {
            break;
        }
        if ($buf == 'shutdown') {
            socket_close($msgsock);
            break 2;
        }
        $talkback = "PHP: You said '$buf'.\n";
        socket_write($msgsock, $talkback, strlen($talkback));
        echo "$buf\n";
    } while (true);
    socket_close($msgsock);
} while (true);
socket_close($sock);

我用@Barmar的评论帮助我建立了一个xinetd服务器

您需要将脚本添加到服务文件中, /etc/services

...
myservice port/tcp # my service
然后添加一个xinetd配置文件,/etc/inetd.d/myservice

# default: on
# description: service script

service myservice
{
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = gleblanc
        server                  = /usr/bin/php
        server_args             = /home/service/scriptname.php
        log_on_success          += DURATION
        nice                    = 10
        disable                 = no
}

但是,它是否可以与现有代码一起正常工作,或者我需要修改它以使输入仍然被接受?如果您的脚本只是输入和输出ASCII,它将正常工作。难道不是
ob_implicit_flush()因为我没有使用httpd,所以没有必要吗?在这个脚本中,
ob\u implicit\u flush()
的目的是清除
echo“$buf\n”。此语句的效果相当于
ini\u集(“隐式\u刷新”,true)
在CLI模式下应该是正确的。您可以让系统管理员配置
xinetd
在套接字上运行脚本。这使用telnet,对吗@Barmar
xinetd
是一个通用服务器,
telnet
是一个客户端。@Barmar但是除了telnet之外,我还必须连接到服务器吗?Telnet充其量是有限的。您可以连接任何可以进行网络连接的软件。例如,
netcat