简体   繁体   中英

PHP Socket and proc_open

I am trying to create a inetd-like service for Windows in PHP for future use with my other application.

So all I can think of is to use Steam Server and proc_open to pipe the stream directly to the process (like inetd). Because on Windows there is no pcntl_fork(), and PHP doesn't support threading.

So far, here is my code. The inetdtest program is a simple program with single printf (written in C). But the problem is that when I connected to my server (via netcat), I got no response message.

<?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();

The code justs works as it stands here (using cat as program and on linux), so the problem lies somewhere in the windows side of things.

For one thing, the option you are passing, to bypass the shell, should be given as

array('bypass_shell'=>true)

This may fix things already. The tricky part with these things, is that you're passing a socket fd to a process, which may or may not be expected to handle that properly. I don't know how these things are done in windows, but cutting cmd out of the equation can only help.

If it still doesn't work, you should create a loop which waits for data (either from network or child processes) and sends data from the network socket to the process pipe, and vice versa.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM