IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation et administration système Perl Discussion :

[Perl] lecture/écriture simultanées sur une socket


Sujet :

Programmation et administration système Perl

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 9
    Points
    9
    Par défaut [Perl] lecture/écriture simultanées sur une socket
    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.enstimac.fr/DocFr/perlip...c%20io::socket

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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.enstimac.fr/DocFr/perlip...c%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 !!

  2. #2
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bonjour,

    je viens apres la bataille, mais ... J'ai le meme probleme, sous linux !!

    As tu trouve la solution ?

    Si c'est le cas, merci de m'en faire part ...

  3. #3
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon, je pense avoir trouvé:
    il suffit de mettre un waitpid($pid, 0) dans la partie du processus père ..

    Ca a l'air de marcher ...

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


    @+

  4. #4
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 9
    Points
    9
    Par défaut
    Salut,

    Mettre un waitpid après le while(<STDIN>) ne change rien parce que c'est dans le while qu'on est bloqué

    Par contre, si on le met avant le while, alors le waitpid fonctionne ... mais du coup le père attend son fils, donc on ne peut pas saisir au clavier tant que le fils écoute la socket. Finalement çà résout par notre problème.

    Quelqu'un sur un autre forum m'a dit que ces scripts fonctionnaient bien chez lui sur Linux, et à priori il n'a pas ajouter de waitpid.

    Malheureusement je n'ai toujours pas de solution.
    Est-tu sûr de n'avoir pas fait autre chose pour que çà fonctionne chez toi ?

  5. #5
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bonjour,

    Alors voici où j'en suis ... (pas très loin je dois l'avouer ...):
    - sous Linux: tout est OK !!
    - si client linux et serveur Windows 2000 (activeperl): OK
    - si serveur linux et client Windows 2000 (activeperl): NOK
    - si client windows XP et serveur Windows XP: NOK

    et ceci sans utiliser de fork() (pour les tests de base) ==> je pense qu'il s'agit d'un probleme de socket entre Perl et Windows.

    On m'a conseillé de faire des threads (à la place du fork()), mais pour l'instant je me focalise sur les sockets ...

    D'autres avancées ??? idées ??? tests ????

    Si tu as trouvé, je suis preneuse !
    @+

  6. #6
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut checksum
    Bonjour,

    me revoila sur les pb de sockets

    Bon, si j'attaque mon serveur perl sous windows avec mon client perl sous linux, tout va bien.
    Si j'attaque un autre serveur (VC++) sous windows avec mon client perl sous linux: ca plante. Pas de chance, c'est le but recherché !!

    On m'a conseillé de verifier les transactions tcp entre les deux programmes avec une appli type ethereal ou wireshark ... Et bien dès qu'il y a des données dans la socket, le checksum est incorrect !!! Pourquoi ? mystère !
    Mais je vais continuer à chercher par là ...

    Une idée ? ou alors la réponse à été trouvée ?
    merci

  7. #7
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bon, en fait, si je prends le ethereal sous linux, ou celui sous windows, je n'ai pas la meme chose !!!
    Les checksums incorrects sont à priori un bug sous linux 2.6. Bref, je me base sur le ethereal sous windows et la c'est bon.

    Pour revenir aux sockets, et bien ... c'est etrange: les sockets reponses ne transitent pas toutes sous tcp et je n'affiche pas toutes celles qui arrivent en plus !
    Je n'y comprends plus rien ...
    Une idée ????

  8. #8
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 15
    Points : 9
    Points
    9
    Par défaut
    Hello

    eh bien je vois que tu n'as pas lâcher l'affaire ! çà fait plaisir

    De mon côté, malheureusement, j'ai été moins patient et j'ai abandonné...

    Je m'étais résigné à me dire que c'était les fork() de Perl sous Windows qui posent problème.
    En effet, j'avais testé avec un client simple qui ne fait que lire OU que écrire sur la socket (donc sans fork), et çà fonctionne (sur Windows je précise).

    Donc ton post ci-dessous me laisse perplexe :
    Citation Envoyé par Joccy Voir le message
    - sous Linux: tout est OK !!
    - si client linux et serveur Windows 2000 (activeperl): OK
    - si serveur linux et client Windows 2000 (activeperl): NOK
    - si client windows XP et serveur Windows XP: NOK

    et ceci sans utiliser de fork() (pour les tests de base)
    Quels scripts as-tu essayé pour échouer avec un client Windows ??

  9. #9
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Hello me revoila encore !

    J'ai résolu mon probleme d'entete et j'arrive ENFIN à attaquer le serveur qui se trouve sous Windows.
    Bon, je n'obtiens toujours pas les réponses: elles n'arrivent que toutes ensemble au bout d'un certain temps ... Je pense que le buffer attend d'etre plein ... Mais quel buffer ? et ou ? comment résoudre cela ?

    Sephiburp, pour répondre à tes questions, j'avoue que j'ai fait tellement de tests que je m'y perds un peu ...
    Pour faire simple, voici mon code en fichier attaché !
    Attention, je travaille sous linux ...

    Bon, si quelqu'un peut nous aider, ce sera super symp'

    @+
    Fichiers attachés Fichiers attachés

  10. #10
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    J'ai teste sous windows: mon fichier ne marche pas sous activeperl (ca bloque effectivement au premier envoi) mais ca fonctionne sous cygwin ....

    A toi de voir maintenant ... Bon courage !

  11. #11
    Membre régulier Avatar de Joccy
    Profil pro
    Inscrit en
    Août 2007
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 153
    Points : 81
    Points
    81
    Par défaut
    Bonjour,
    Bon, j'ai enfin mes reponses venant du serveur (meme si je ne sais pas reellement pourquoi ca marche maintenant et pas avant): seul le pb de fin de ligne ???? en tout cas en utilisant la fonction recv() de la socket,ca marche .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    #the if block is in father process
    if ($kidpid) 
    	{
    	 # copy socket in std output: listen to the server
    	# Rq: le serveur Opera n'a pas de caractere de fin de ligne
    	my $Response;
    	my $iRes = $socket->recv($Response, 1024); 
    	if (defined $iRes)
    	  {
    	    my $iLen = length($Response);
    	    print "Opera> $Response\n";
    	  }
     
    	}
    # the else block is in kid process
    else
    Bon, Sephiburb, je suis désolée de ne pas pouvoir t'aider plus. As tu résolu ton pb ?

    @+

Discussions similaires

  1. Réponses: 0
    Dernier message: 23/02/2015, 05h50
  2. lecture sur une socket
    Par fattouch_squall dans le forum Développement
    Réponses: 7
    Dernier message: 22/12/2007, 13h57
  3. threads simultanes sur une meme socket
    Par khayyam90 dans le forum Développement
    Réponses: 9
    Dernier message: 28/01/2006, 16h03
  4. Réponses: 2
    Dernier message: 29/09/2004, 09h07
  5. Réponses: 7
    Dernier message: 08/03/2004, 15h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo