2009-06-14 7 views
4

Jusqu'à présent, j'ai écrit un serveur Perl qui fonctionne constamment en arrière-plan, lorsqu'il reçoit des connexions entrantes, un processus est forké et qui gère ensuite cette connexion. Ce que je veux finalement pouvoir faire, c'est accepter les connexions php entrantes via le socket, bien sûr, exécuter ces commandes, puis relayer et renvoyer les informations. Jusqu'à présent, j'ai réussi à obtenir 100% de succès avec un client script Perl mais cela ne fonctionne pas à 100% avec un php.PHP à Perl Socket Communication

[Au lieu de coller la paroi du trou de texte est ici l'envoi réel et recevoir section.]

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 :[email protected]\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); 
      } 
     } 
    } 

Comme je l'ai dit cela fonctionne très bien avec un client écrit perl à la fois localement et à distance, mais ne fonctionne pas 100% avec PHP, ce que je veux dire par 100% est le fait que le serveur va recevoir la commande, mais est incapable de le renvoyer, ou le serveur est capable de recive la commande, mais le client n'est pas capable de lire la réponse.

Voici le client [php] que j'ai le plus travaillé.

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

Voici le client Perl travaillant

#!/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; 
    } 
} 

Si elle aide je peux poster tout le serveur si nécessaire.

+4

Wow. Vous devriez vraiment essayer Net :: Server ou, mieux encore, AnyEvent :: Socket :: tcp_server. Mettre en œuvre tout cela manuellement a été une énorme perte de temps ... et cela ne fonctionne même pas. – jrockway

+0

Peut-être que vous pourriez essayer d'avoir le serveur détecter les erreurs et les erreurs de journal sur les lectures ou les écritures, et voir si l'erreur est utile dans le diagnostic du problème. Pourquoi votre client Perl forking mais votre client PHP n'est pas? – ysth

+0

Cela semble un peu un gâchis donc je regarderai probablement dans Net :: Server et l'autre. La raison pour laquelle le client Perl forks est parce que c'était la façon dont il était quand je l'ai tiré du filet pour voir rapidement si cela fonctionnait de cette façon. – RyanM

Répondre

2

Votre serveur attend que les clients envoient des lignes. Mais votre client PHP envoie seulement deux caractères "ls". Cela signifie que votre serveur attendra toujours que le client envoie une nouvelle ligne.

Edit:

  1. Votre code Perl (serveur) utilise un protocole orienté ligne. Votre code PHP ne l'est pas. Vous ne devriez pas mélanger les deux moyens de communication.
  2. Votre client Perl utilise un protocole orienté ligne. Le code PHP doit utiliser fgets() et non fread().
  3. Sur votre serveur, le processus parent garde le socket ouvert au client. C'est pourquoi le socket n'est pas fermé lorsque l'enfant quitte et c'est probablement pourquoi votre client ne verra pas un EOF jusqu'à ce qu'un autre client se connecte au serveur.
+0

while (defined ($ line = <$client>)) { print "Commande en cours"; ## Allons-nous passé ce point? $ command = '$ line'; print commande $; print "Envoyer une réponse"; print commande $ client $ ou die ($!) print "Réponse envoyée"; } Si ce que vous dites est le cas, comment se fait-il que j'ajoute des "marqueurs d'impression" jusqu'à la réponse envoyée sans suspension ou "attente pour toujours" ou saute-t-elle simplement les autres et passe-t-elle à autre chose? – RyanM

+0

Était-ce une question rhétorique? – innaM

+0

Vous avez probablement un tampon en jeu ici. –

Questions connexes