PHP Socket и proc_open - PullRequest
       5

PHP Socket и proc_open

0 голосов
/ 31 июля 2010

Я пытаюсь создать Inetd-подобный сервис для Windows в PHP для будущего использования с другим моим приложением.

Поэтому все, что я могу придумать, - это использовать 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();

1 Ответ

1 голос
/ 31 июля 2010

Код justs работает в том виде, в каком он здесь стоит (используя cat в качестве программы и в linux), поэтому проблема лежит где-то на стороне Windows.

С одной стороны, опция, которую вы передаете, чтобы обойти оболочку, должна быть задана как

array('bypass_shell'=>true)

Это уже может все исправить. Сложность в этих вещах заключается в том, что вы передаете socket fd процессу, который может или не может обрабатывать это должным образом. Я не знаю, как это делается в окнах, но вычеркнуть cmd из уравнения может только помочь.

Если это все еще не работает, вы должны создать цикл, который ожидает данные (из сетевых или дочерних процессов) и отправляет данные из сетевого сокета в канал процесса, и наоборот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...