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

Réseau/Web Python Discussion :

Problème de communication par socket


Sujet :

Réseau/Web Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Problème de communication par socket
    Bonjour,

    Je débute avec Python, et je rencontre une difficulté dans l'utilisation de socket (client):
    J'ai un serveur qui écoute sur un port particulier. Les échanges avec lui se font selon le schéma suivant :
    envoi vers le serveur :
    mot_cle [option]
    Le mot-cle est sur 4 caractères, l'option est facultative et dépend de la commande choisie

    réponse du serveur :
    code_retour-données
    code_retour-données
    code_retour données

    le code_retour est une valeur numérique sur 3 caractères. La réponse tient en une ou plusieurs lignes, la dernière étant différenciée par un espace à la place du tiret entre le code retour et les données.

    Mon problème est le suivant :
    après la connexion à la socket, le message d'accueil arrive parfois en entier, parfois non. Dans ce dernier cas, une lecture supplémentaire avec recv me donne la suite du message. Ce qui est bizarre, c'est que ce comportement est aléatoire. Pourtant, les messsages sont brefs (80 car max par ligne). Du coup, tous les messages de retours suivants sont décalés par rapport aux commandes d'envoi (send).

    Voici un extrait de mon code :
    ******************debut de l'extrait de 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
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(10.)
    try:
        s.connect((HOST, PORT))
    except:
        print "erreur de connexion au serveur"
    else:
        rep=s.recv(1024)
        print "Connecté au serveur"
     
    s.send("CMD1\r\n")
    rep = s.recv(1024).strip('\r\n')
     
    s.send("CMD2\r\n")
    rep = s.recv(1024).strip('\r\n')
     
    s.send("CMD3\r\n")
    rep = s.recv(1024).strip('\r\n')
    ******************fin de l'extrait de code**************

    En résumé, la ligne contenant recv qui suit le send avec CMD1 renvoie souvent (mais pas toujours) la fin du message d'accueil alors que l'intégralité devrait être envoyée dans la branche "else" du "try".

    En faisant la même opération avec telnet <host> <port>, le comportement est correct (un message complet pour chaque commande).

    Quelqu'un aurait-il une idée ? Qu'ai-je raté dans la compréhension du module socket ?

    Merci par avance de votre aide (et d'avoir eu la patience de lire jusque là
    Olivier.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 18
    Points : 17
    Points
    17
    Par défaut
    Bonjour

    Pour citer du code, utilise la balise Code de l'éditeur (représenté par un #), merci

    Pour ton problème, deux choses :
    1) à quoi te sert le s.settimeout(10.) ?
    2) à moins que mes tests soient foireux (parce qu'ils fonctionnent bien ), ce doit être ton script serveur qui pose problème

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Désolé de n'avoir pas balisé le code (il n'y a pas qu'avec Python que je débute )

    1- J'ai mis le s.settimeout(10.) afin que le script en question se termine si le serveur ne répond pas au bout de 10s (comme c'est sur la même machine, j'estime ce "timeout" largement suffisant). En réalité, les séquences send et recv qui suivent sont dans la branche "else" du "try", ce qui n'apparaissait pas dans mon post initial. De plus, le script se termine en cas d'erreur à la connexion (après le print).

    2- Donc si je comprends bien, mon code (client) python est correct ?
    Le code serveur (pilotage par le réseau d'un magnétoscope numérique VDR via un protocole dédié SDVRP pour tout dire - cf http://www.cadsoft.de/vdr/ pour ceux que cela intéresse) est écrit en C++. Il semble pourtant bien fonctionner si on y accède via telnet ou nc par exemple. Je ne vois vraiment pas pourquoi le message d'accueil de la connexion est coupé en 2 avec python et pas avec telnet ni nc. Sur quel(s) caractère(s) la méthode recv se base-t-elle pour considérer que la lecture est terminée ?

    Merci de votre aide

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je me réponds à moi-même juste pour faire profiter tout le monde de la solution...

    En réalité, le problème ne vient pas du code, mais de l'implémentation. Tel que je l'ai compris en fin de compte, le mode de fonctionnement des sockets est très lié à la gestion du réseau (ou plus exactement des paquets), indépendamment des données véhiculées. En d'autres termes, ce sont les couches réseaux qui décident quant elles "flushent" les données selon des critères qui dépendent notamment de la taille des paquets. En aucun cas ne sont interprétés des caractères tels que EOF, EOD, Ctrl-Z, etc... C'est la raison pour laquelle d'une fois sur l'autre, la lecture d'un même message peut ramener plus ou moins de données.

    En conséquence, pour récupérer des messages cohérents et surtout complets, il est impératif de connaitre le protocole d'échange utilisé via une socket (soit le nombre de caractères à lire au total, soit identifier une séquence 'fin de message' particulière), et éventuellement de lire par itérations.

    Pour ceux que cela intéresse, je suggère une lecture attentive du document à l'adresse : http://www.amk.ca/python/howto/sockets

    On peut y lire en particulier :
    as the designer, you will have to decide what the rules of etiquette are for a conversation

    Olivier.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de communication par socket
    Par FabaCoeur dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 22/06/2010, 10h00
  2. Réponses: 5
    Dernier message: 29/03/2007, 22h26
  3. Communication par socket
    Par cybermarcel dans le forum Ruby
    Réponses: 5
    Dernier message: 14/01/2007, 23h08
  4. [Omnis] Communication par Socket
    Par y0p dans le forum WinDev
    Réponses: 4
    Dernier message: 15/06/2006, 09h02
  5. Problème de communication par sockets
    Par Linio dans le forum Entrée/Sortie
    Réponses: 33
    Dernier message: 06/05/2006, 18h50

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