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

Python Discussion :

Client / serveur à 2 balles : entre le C et Python, mon coeur balance (pas)


Sujet :

Python

  1. #1
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut Client / serveur à 2 balles : entre le C et Python, mon coeur balance (pas)
    Bonjour à tous,

    je me suis codé un mini-client en C (pour envoyer des infos de debug sans (trop) consommer de CPU) et un mini-serveur en python pour recevoir ces fameuses infos.

    Le hic, c'est qu'après 2 ou 3 envois réussis, le send du coté client me revoie une erreur alors que le serveur semble en bonne santé.

    Pour essayer d'y voir plus clair, j'ai codé l'équivalant du serveur python en C, et là ça marche au poil.

    Du coup, je me (vous) demande quelle différence il peut bien y avoir entre mon serveur python et mon serveur C ?

    Voici le code du serveur python :
    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
    import os
    import sys
    import time
    import SocketServer
     
     
    def DumpingServer ( port,timeout ):
        class TCPHandler ( SocketServer.BaseRequestHandler ):
            def handle(self):
                print self.request.recv( 2000 )
        def timed_out () : server.is_alive = False
        server = SocketServer.TCPServer(('localhost',port),TCPHandler ) # test en local pour le moment
        server.timeout        = timeout   # <timeout> sec sans requête => terminaison
        server.is_alive       = True      # un nouvel attribut à <server>
        server.handle_timeout = timed_out
        while server.is_alive :
            server.handle_request()
     
    DumpingServer( 55555,60*5 ) # timeout de 5min
    Vous voyez que mon serveur est des plus simples, et très largement inspirés des exemples que l'on peut trouver sur la doc officielle.
    Il écoute le port 55555 (en dur) et print tout ce qu'il reçoit.

    Mon client en C (sous Visual Studio 2005) est un peu trop long pour que je le copie-colle ici, mais en gros, il s'articule autour de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SOCKET socketid ;          
    socketid  = socket( AF_INET,SOCK_STREAM,IPPROTO_IP ) ;
     
    struct sockaddr_in client ;
    client.sin_family      = AF_INET ;
    client.sin_addr.s_addr = inet_addr( "127.0.0.1" ) ; // test en local pour le moment
    client.sin_port        = htons( 55555 ) ;
     
    connect( socketid,(struct sockaddr*)&client,sizeof( client )) ;
     
    for (;;)           
        {                         
        send( m->socketid,buffer,size,0 ) ; // buffer contient des infos de debug...
        }
    Après 2 ou 3 envois + réceptions réussis, le send échoue et l'erreur est "10053 : Software caused connection abort."

    Mon serveur en C (avec qui les envois+réceptions sont ok) ressemble au client :
    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
    SOCKET connfd = socket( AF_INET,SOCK_STREAM,IPPROTO_IP ) ;
     
    struct sockaddr_in servaddr ;
    servaddr.sin_family      = AF_INET ;
    servaddr.sin_addr.s_addr = htonl( INADDR_ANY ) ;
    servaddr.sin_port        = htons( 55555 ) ;
     
    bind( connfd,(struct sockaddr*)&servaddr,sizeof( servaddr )) ;
    listen( connfd,1 ) ;
    SOCKET socketid = accept( connfd,NULL,NULL ) ;
     
    for (;;)    
        {
        char buffer [1000] ;
        int received = recv( m->socketid,buffer,1000,0 ) ;
        fwrite( buffer,received,1,output ) ;
        }
    Si quelqu'un comprend ce qui cloche dans mon serveur python, son avis serait le bienvenu.

    Merci de m'avoir lu et de vos réponses !

  2. #2
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Bonjour,

    Quelques idées qui ne régleront sans doute rien:
    - Est ce que par hasard self.request.recv( 2000 ) ne serait pas bloquant ? Il faudra attendre 2000 caractères pour voir printer quelquechose, et d'ici la, peut être qu'un timeout aura fait planter le serveur. Peut être faut il recv() des plus petits paquets.
    - Dans le même genre d'idées, il faut laisser le temps au serveur de lire, et donc ne pas envoyer trop d'information trop vite.
    - Le serveur python tourne-t'il dans un autre processus (Je ne crois pas que SocketServer soit thread safe) ?

    Je te conseille de faire varier le nombre/fréquence/longueur des messages envoyés pour tester la reproductibilité du bug, ça te donnera peut être une piste

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 474
    Points : 9 277
    Points
    9 277
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je me suis déjà un peu amusé avec ça: http://python.jpvweb.com/mesrecettes...rveur_tcp_base.

  4. #4
    Membre confirmé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Points : 455
    Points
    455
    Billets dans le blog
    1
    Par défaut
    Merci messieurs, mais malheureusement il n'y a pas d'amélioration :

    tyrtamos : ton exemple de serveur synchrone ressemble beaucoup au mien à un détail près : il utilise un serve_forever plutôt qu'une boucle en attente d'un time out.
    Du coup, j'ai fait l'essai : ça ne change rien...
    En tout cas, je garde un lien vers ton tuto pour y revenir plus tard...

    VV33D : en fait le paramètre de recv est juste une limite max du nombre d'octets qu'il peut recevoir. Le faire varier ne change rien.
    Et ce n'est pas un problème de timeout : en ajoutant des traces, je constate qu'il est bien en attente dans le recv au moment où le client échoue.

  5. #5
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    je ne peux que réitérer mon conseil, ca m'a beaucoup aidé à debugger mes serveurs.
    Je te conseille de faire varier le nombre/fréquence/longueur des messages envoyés pour tester la reproductibilité du bug, ça te donnera peut être une piste
    Sinon, si tu suspectes vraiment un problème de conversion de données entre C et Python, tu peux coder un petit client test en Python et voir comment se comporte le serveur avec lui.

    Bon courage

Discussions similaires

  1. Réponses: 15
    Dernier message: 20/02/2015, 13h46
  2. Entre CStr et ToString, mon coeur balance
    Par Kropernic dans le forum VB.NET
    Réponses: 12
    Dernier message: 27/06/2011, 10h25
  3. Entre SB64 et SB128 mon coeur balance
    Par ludosoft dans le forum Composants
    Réponses: 3
    Dernier message: 24/08/2007, 08h40
  4. Entre L'api Win32 et SDL mon coeur balance
    Par mechouille dans le forum API graphiques
    Réponses: 16
    Dernier message: 13/12/2006, 16h01
  5. Réponses: 3
    Dernier message: 30/03/2004, 09h38

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