Связь PHP с Perl Socket - PullRequest
       9

Связь PHP с Perl Socket

4 голосов
/ 14 июня 2009

До сих пор я написал Perl-сервер, который постоянно работает в фоновом режиме, когда он получает входящие соединения, процесс разветвляется и затем обрабатывает это одно соединение. В конечном итоге я хочу, чтобы он мог принимать входящие php-соединения через сокет, конечно же, запускать эти команды, а затем ретранслировать и возвращать информацию. До сих пор мне удавалось добиться того, чтобы это работало на 100% с клиентом, написанным на Perl, но оно не работает на 100% с php.

[Вместо того, чтобы вставлять дыру в стене, здесь есть фактический раздел отправки и получения.]

print "Binding to port ...\n";
$server = IO::Socket::INET->new(
            Listen => 1, 
            LocalAddr => $_server, 
            LocalPort => $_port, 
            Proto => 'tcp', 
            Reuse => 1, Type => SOCK_STREAM) || die "Cant bind :$@\n";
$proccess = fork();
if ($proccess) {
    kill(0);
}
else {
    while(1) {
        while ($client = $server->accept()) {
            $client->autoflush(1);
            $con_handle = fork();
            if ($con_handle) {
                print "Child Spawned [$con_handle]\n";
            }else{
                while (defined($line = <$client>)) {
                    $command = `$line`;
                    print $client $command;
                }
                exit(0);
            }
        }
    }

Как я уже сказал, это прекрасно работает с клиентом, написанным на Perl, локально и удаленно, но не работает на 100% с php, что я имею в виду под 100% тем, что сервер получит команду, но не сможет ее отправить назад, или сервер может получить команду, но клиент не может прочитать ответ.

Вот клиент [php], с которым я работаю больше всего.

$handle = fsockopen("tcp://xx.xx.xx.xx",1234);
fwrite($handle,"ls");
echo fread($handle);
fclose($handle);

Вот рабочий клиент Perl

#!/usr/bin/perl -w
use strict;
use IO::Socket;
my ($host, $port, $kidpid, $handle, $line);

unless (@ARGV == 2) { die "usage: $0 host port" }
($host, $port) = @ARGV;

# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(Proto     => "tcp",
                                PeerAddr  => $host,
                                PeerPort  => $port)
       or die "can't connect to port $port on $host: $!";

$handle->autoflush(1);              # so output gets there right away
print STDERR "[Connected to $host:$port]\n";

# split the program into two processes, identical twins
die "can't fork: $!" unless defined($kidpid = fork());

# the if{} block runs only in the parent process
if ($kidpid) {
    # copy the socket to standard output
    while (defined ($line = <$handle>)) {
        print STDOUT $line;
    }
    kill("TERM", $kidpid);                  # send SIGTERM to child
}
# the else{} block runs only in the child process
else {
    # copy standard input to the socket
    while (defined ($line = <STDIN>)) {
        print $handle $line;
    }
}

Если это поможет, я могу при необходимости опубликовать весь сервер.

1 Ответ

2 голосов
/ 14 июня 2009

Ваш сервер ожидает от клиентов отправки строк. Но ваш PHP-клиент отправляет только два символа "ls". Это означает, что ваш сервер всегда будет ждать, пока клиент отправит новую строку.

Edit:

  1. Ваш Perl (серверный) код использует линейно-ориентированный протокол. Ваш PHP-код не является. Не стоит смешивать оба способа общения.
  2. Ваш Perl-клиент использует линейно-ориентированный протокол.
  3. Ваш PHP-код должен использовать fgets(), а не fread().
  4. На вашем сервере родительский процесс держит сокет для клиента открытым. Вот почему сокет не закрывается при выходе ребенка, и, вероятно, поэтому ваш клиент не увидит EOF, пока другой клиент не подключится к серверу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...