我正在尝试在PHP中为Windows创建类似inetd的服务,以便将来与我的其他应用程序一起使用。
所以我能想到的是使用Steam Server和proc_open将流直接传递给进程(如inetd)。因为在Windows上没有pcntl_fork(),PHP不支持线程。
到目前为止,这是我的代码。 inetdtest
程序是一个简单的程序,单printf
(用C语言编写)。但问题是,当我连接到我的服务器(通过netcat)时,我没有收到任何响应消息。
<?php
define ('SERVICE_COMMAND', 'inetdtest');
define ('SERVICE_PORT', 35123);
function main() {
echo "Simple inetd starting...\n";
$socket = stream_socket_server('tcp://0.0.0.0:' . SERVICE_PORT, $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);
if ($socket === false) {
echo "Can't bind to service port.\n";
echo "[$errno] $errstr";
die(1);
}
$processes = array();
while (true) {
$current = @stream_socket_accept($socket, 5, $host);
if ($current !== false) {
echo 'Incomming connection from client ' . $host . "\n";
echo "Lunching child process... ";
$io = array(
0 => $current,
1 => $current,
2 => array('file', 'stderr.log', 'a')
);
$proc = proc_open(SERVICE_COMMAND, $io, $pipes, NULL, NULL, array('bypass_shell'));
$status = proc_get_status($proc);
echo " DONE! PID : {$status['pid']}\n";
$processes[] = array($current, $proc);
}
foreach ($processes as $k=>$v) {
$status = proc_get_status($v[1]);
if (false === $status['running']) {
echo "Finalizing process {$status['pid']}... ";
fflush($v[0]);
fclose($v[0]);
proc_close($v[1]);
unset($processes[$k]);
echo "DONE!\n";
}
}
}
}
main();
答案 0 :(得分:1)
代码就像它在这里一样工作(使用cat
作为程序和linux),所以问题出在窗口的某个方面。
首先,你传递的选项,绕过shell,应该是
array('bypass_shell'=>true)
这可能已经解决了问题。这些事情的棘手部分在于,您正在将套接字 fd传递给进程,该进程可能会或可能不会正确处理。我不知道这些事情是如何在Windows中完成的,但是将cmd
排除在等式之外只会有所帮助。
如果它仍然不起作用,您应该创建一个等待数据的循环(来自网络或子进程)并将数据从网络套接字发送到进程管道,反之亦然。