[PERL] lecture/écriture sur une socket

Fermé
sephiburp Messages postés 4 Date d'inscription lundi 29 octobre 2001 Statut Membre Dernière intervention 19 août 2007 - 11 août 2007 à 12:47
Super_carotte Messages postés 1419 Date d'inscription mardi 8 janvier 2008 Statut Membre Dernière intervention 27 janvier 2015 - 24 nov. 2010 à 11:51
Bonjour,

J'aimerais faire du client-serveur intéractif en Perl.

J'ai un serveur.pl qui fonctionne correctement, j'ai repris ce script : http://perl.mines-albi.fr/DocFr/perlipc.html#serveurs%20tcp%20avec%20io::socket


Et j'ai un client.pl dont voici le code :

use IO::Socket;
use warnings;
use strict;

my ($sock, $kidpid);

$sock = IO::Socket::INET->new(Proto     => "tcp",
                              PeerAddr  => "192.168.0.11",
                              PeerPort  => 9000)
                        || die "Failed : $!";
$sock->autoflush(1);

$kidpid = fork();
die "can't fork: $!" if ! defined($kidpid);

if ($kidpid) {
    # PERE : Ecoute des entrées clavier et envoi à la socket
    while (<STDIN>) { print $sock $_; }
} else {
    # FILS : Ecoute de la socket et affichage à l'écran
    while (<$sock>) { print STDOUT $_; }
}

close $sock;


Mon problème :
La connexion réussie, et le client reçoit et affiche les messages d'accueil du serveur.
Mais après la première ligne rentrée au clavier, çà se "bloque". Et le serveur ne recoit même pas cette ligne.

Après un déboggage "approfondi", j'en ai conclu que le processus père n'arrive pas à écrire sur la socket tant que le fils boucle sur cette même socket pour écouter.
En effet, si je ne fais que écrire ou que écouter, cà fonctionne très bien.

J'ai essayer plusieurs scripts client trouvés sur le net et j'en arrive toujours au même problème.
Même celui proposé ici réagit pareil : http://perl.mines-albi.fr/DocFr/perlipc.html#client%20interactif%20avec%20io::socket

Je suis sous Windows 2000 et j'utilise Perl 5.8.8
Est-ce à cause de Windows qui gère mal le fork() ou les sockets ?

Merci d'avance pour votre aide !!

8 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
19 août 2007 à 16:02
Salut,

voici un exemple, à toi d'adapter
server
#!/usr/bin/perl
use strict;use warnings;
use IO::Socket;

my $serveur = IO::Socket::INET->new(LocalPort => 10000,
                                    Type      => SOCK_STREAM,
                                    Reuse     => 1,
                                    Listen    => 10)
or die "Impossible serveur tcp sur le port 10000 : $@\n";

while (my $client = $serveur->accept()) {
  next if my $pid = fork;
  close($serveur);
  print "*** Debut de connexion ***\n";
  print $client "Bienvenu sur le SERVER !\n--- Je suis PID $$ ---\n";
  while( my $rep = <$client>) {
    print $rep;
    if ( $rep =~ /^QUIT/i) {
      close($client);
    }
    print "*** Fin de connexion sur PID $$ ***\n";
    exit;
  }continu {
    close($client);
  }
}
$SIG{CHLD} = 'IGNORE';
__END__
le client
#!/usr/bin/perl
use strict;use warnings;
use IO::Socket;

my $socket = IO::Socket::INET->new(Proto    => "tcp",
                                   PeerAddr => "10.0.0.5",
                                   PeerPort => 10000)
or die "Failed : $@\n";

print "*** Debut de connexion ***\n";
while(my $reponse=<$socket>){
  print "Le serveur a dit : $reponse";
  print $socket "Au revoir SERVEUR!!!\n";
}
print "*** Fin de connexion ***\n";
__END__
Sur le serveur
lami20j@deb:~$ perl ccm.pl
*** Debut de connexion ***
Au revoir SERVEUR!!!
*** Fin de connexion sur PID 12855 ***
Sur le client
lami20j@debian:~$ perl ccm.pl
*** Debut de connexion ***
Le serveur a dit : Bienvenu sur le SERVER !
Le serveur a dit : --- Je suis PID 12855 ---
*** Fin de connexion ***
lami20j@debian:~$

7
sephiburp Messages postés 4 Date d'inscription lundi 29 octobre 2001 Statut Membre Dernière intervention 19 août 2007 3
19 août 2007 à 11:44
Je relance ma question,
Une idée chez quelqu'un ?
0
sephiburp Messages postés 4 Date d'inscription lundi 29 octobre 2001 Statut Membre Dernière intervention 19 août 2007 3
19 août 2007 à 22:03
bonsoir lami, merci pour ta réponse.
Mais le client que tu proposes ne fait que lire la socket.

J'aimerais avoir un client qui écrit et lit simultanément sur une socket, d'où l'utilisation d'un fork avec un père qui écrit et un fils qui lit.
Rappel du problème : le père bloque sur l'écriture de la socket tant que le fils boucle pour la lire.

J'essaierai tout de même les paramètres de ton exemple que je n'ai jamais utilisé (Type=>SOCK_STREAM pour la création de l'objet et $SIG{CHLD}='IGNORE' ...)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
19 août 2007 à 22:46
Re,

Mais le client que tu proposes ne fait que lire la socket.
Il écrit aussi Au revoir SERVEUR !!!

J'aimerais avoir un client qui écrit et lit simultanément sur une socket, d'où l'utilisation d'un fork avec un père qui écrit et un fils qui lit.
Rappel du problème : le père bloque sur l'écriture de la socket tant que le fils boucle pour la lire.


Ok, je vais voir ça ;-)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Petite remarque hors sujet.

Le mot socket est masculin.

Sinon, on écrit aussi une soquette, mais c'est autre chose.

Sinon, pour compléter un peu le sujet, il t'est possible de faire un thread plutôt que de créer un processus avec un fork pour lire et écrire simultanément sur ton socket.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
14 juin 2008 à 23:29
Toujours hors sujet

Semble-t-il que certains traducteurs spécialisés pense que socket c'est un féminin, vu qu'il s'agit d'une association d'une adresse IP et d'un numéro de port

Exemple :

Livre TCP/IP 3ème édition, Edition O'Reilly - Traduction Emmanuel Chaput et Stéphane Larroque


Je cite depuis Page 50
L'association d'une adresse IP et d'un numéro de port est appelée une socket

Livre Perl en Action, Edition O'Reilly - Traduction Sébastien Blondeel

Je cite depuis Page 702

La fonction socket crée une socket, la fonction bind donne à une socket un nom local, la fonction connect connecte la socket à une autre socket, qui peut être distante, la fonction listen prépare une socket à recevoir des connexions d'autres socket ......

On peut communiquer via une socket ...


Livre Programmation en Perl, 3ème edition, Editon O'Reilly - Traduction Philippe Bruhat, Kai Carver et Gérald Sédrati

Je cite
Glosaire Page 974

socket - ..... La chose la plus importante concernant une socket est son adresse réseau.....

Page 409
Bien que les sockets aient été inventées sur BSD, elles se sont rapidement répandues....

Page 746

Cette fonction ouvre une socket du type spécifié...


Livre Programmation système en C sous Linux par Christophe Blaess

Je cite
Page 132

Ces données peuvent être transmises sur une socket TCP/IP avec une priorité ....

Page 516

Les programmes offrant des services réseau peuvent choisir d'utiliser leur propre système de connexion, construisant une socket et restant à l'écoute ....

0
Effectivement, tes sources sont fiables, même si je trouve que ça ne sonne pas très bien.

Dans mon message précédent, je proposais l'utilisation des threads.

Débutant dans ce langage, je viens de découvrir à quel point le modèle de thread est mauvais en PERL.

Les variables ne sont pas partagées par défaut entre les threads. Il faut préciser le mot clé shared pour les rendre partagées. Bon, pourquoi pas.

Toutefois, les types structurés ou objets sont partageables que si les éléments qui le composent sont partageables. Ainsi, il devient impossible de partager un socket. Ainsi, la solution d'avoir un thread qui consomme et l'autre qui écrit n'est plus viable.

Quelqu'un saurait-il comment outrepasser cette limitation du modèle de thread de PERL ?
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
15 juin 2008 à 11:34
0
bien j'avou que j'ai exactement le meme soucis que toi, peu importe les codes testés, je ne peux que lire dans la socket, ou que ecrire dessus, mais pas les deux, et ce soucis ne se pose que sous windows ..

sous linux, aucun soucis, donc j'en deduis comme toi, un soucis de fork() avec windows..

Pour ce qui concerne les threads, je ne vois pas trop comment organiser mon code pour faire le serveur.

Si il y aurait kk1 pour eclairer cette situation .. Merci :)
0
re bonjour,

bien voila, apres quelques tests, j'ai reussi a faire fonctionner le premier code que tu as posté sur XP, il m'as fallu placer cette commande " waitpid($pid,0); ", juse avant la boucle while du pid pere ..

voila dis moi si pour toi, cela resous le soucis
0
Super_carotte Messages postés 1419 Date d'inscription mardi 8 janvier 2008 Statut Membre Dernière intervention 27 janvier 2015 127
24 nov. 2010 à 11:51
Bonjour,
Quand tu dis: "j'ai reussi a faire fonctionner le premier code que tu as posté sur XP" tu parle du premier code posté par Sephibur ou Lami20j?
0