类似SSH的php套接字服务器
我有一个CLI php脚本,用于收集用户输入、处理它并返回基于它的信息。目前,只有通过SSH连接到PHP所在的服务器并运行类似SSH的php套接字服务器,php,sockets,Php,Sockets,我有一个CLI php脚本,用于收集用户输入、处理它并返回基于它的信息。目前,只有通过SSH连接到PHP所在的服务器并运行phpscriptname.PHP,才能使用它,但是,我知道PHP可以创建套接字服务器。有没有可能,如果有,如何创建一个套接字服务器来侦听连接,并且在用户连接后,为脚本提供一个类似终端的环境,直到用户断开连接为止?对于每个连接的用户,它也将是一个不同的脚本实例。不需要身份验证 编辑:如果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,对吗@Barmarxinetd
是一个通用服务器,telnet
是一个客户端。@Barmar但是除了telnet之外,我还必须连接到服务器吗?Telnet充其量是有限的。您可以连接任何可以进行网络连接的软件。例如,netcat
。