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 :

Problème avec une appli Client/Serveur au niveau de l'encodage des réponses...


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Problème avec une appli Client/Serveur au niveau de l'encodage des réponses...
    Bonjour,

    Je suis en train de programmer une petite application Client/Serveur qui fonctionne un peu de cette façon:

    Le client cherche à se connecter perpétuellement au serveur.
    Par conséquent, lorsque j'ouvre le serveur de mon côté, le client s'y connecte (c'est donc une "reverse connection", on retrouve ce principe dans Metasploit).
    Le client se met en attente de requêtes de la part de mon serveur.
    Lorsqu'il reçoit une réponse, il la traite (selon une série de if, elif et else) et renvoie une réponse au serveur (commande exécuté avec succès, erreur non spécifié ou plus généralement un message personnalisé...)
    Et voila pour le principe.

    Tout le bousin fonctionne plus ou moins bien (il reste encore énormément de choses à ajouter et d'autre à corriger).
    Je m'attelle en ce moment à la correction de bugs évidents.

    Je vous met ici la partie de mon programme qui pose problème:
    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
     
        #ls
        elif comm == "ls":
            try:
                liste = os.listdir(".")
                response = ""
                SOCK.send("buffer".encode("Utf-8"))
                for i in liste:
                    if os.path.isdir(i):
                        response = response + "\n" + "REP--->  " + i + "/"
                    elif os.path.isfile(i):
                        response = response + "\n" + "FILE-->  " + i
                    else:
                        response = response + "\n" + "UNKN-->  " + i + "~"
                SOCK.send(response.encode("Utf-8"))
                del response
            except:
                SOCK.send("Mauvais repertoire".encode("Utf-8"))
    (c'est la partie Client)
    La variable comm, est la commande qu'a envoyé le serveur.
    "ls" est une commande UNIX bien connue permettant d'afficher le contenu du répertoire actuelle.
    Donc lorsque le serveur tape "ls", le client tentera d’exécuter : os.listdir(".").
    Si il n'y arrive pas, il lui renvoie "Mauvais répertoire".
    L'envoie de "buffer" précise seulement au serveur d'augmenter la taille de son buffer.
    Donc de passer de ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    response = conn.recv(1024).decode("Utf-8")
    à ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(conn.recv(10240).decode("Utf-8"))
    (il attend donc une réponse 10x plus grande, le contenu des répertoire oblige...)


    Enfin bref.
    Le vrai problème réside dans le fait que si le répertoire à afficher contient des caractères un peu spéciaux, tout part en sucette...

    En effet, comme on le voit, la liste des éléments (les noms des fichiers et répertoires qui se trouve dans le répertoire courant) seront formaté d'une façon particulière puis inséré dans la variable "response" qui sera par la suite envoyé au serveur.

    Sauf que de son côté, le serveur fait ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(conn.recv(10240).decode("Utf-8"))
    Or, si ma variable "response" contient des caractères spéciaux le serveur plantera à cause d'une erreur: UnicodeEncodeError (et le client aussi par la même occasion à cause d'une socket.error).


    En fait, l'erreur n'est pas déclencher à "decode("Utf-8")" mais lors du print effectué par le serveur.
    J'ai donc trouvé un moyen qui me déplait fortement :
    Faire afficher le contenu de la variable "i" du côté client dans un try: et en cas d'erreur, passer dans un except puis faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    reponse = response + "\n" + "ENCODE ERROR"
    Cela fonctionne mais pose un problème plus gros encore:
    Ce programme à pour but d'être passif, si le client voit s'afficher la liste entière d'un de ses répertoires, ça risque de ne plus passer inaperçu...

    Ma question est la suivante:
    Existe-t-il un moyen de faire vérifier "response" par le client et de remplacer les lignes incriminées par "ENCODE ERROR" sans afficher quoi que ce soit côté client ?

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 893
    Points : 7 249
    Points
    7 249
    Par défaut
    Avec la version 3 de python?

    C'est un vrai problème ce type d'erreurs en version 2.x, mais il me semble que c'est résolu avec la version 3.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Oui, avec Python 3.2.1.

    La récupération du contenu d'un dossier se passe bien, tout comme l'encodage, l'envoi par socket au serveur ainsi que le décodage de la part du serveur.
    C'est juste que celui-ci ne parvient pas à afficher ce qu'il à reçu lorsque ce contenu contient des caractères spéciaux...
    UnicodeEncodeError + crash des deux côtés (Serveur et client (celui-ci ayant perdu la connexion au serveur).
    C'est en effet assez problématique.
    N'y a t-il pas moyen de faire vérifier la réponse du côté serveur avant de l'envoyer au serveur ? (autre qu'en faisant un print, car même si cela fonctionne ce n'est pas discret du tout...)

    EDIT:
    Panique!
    Je possédais jusqu'alors la version 32bits de Python (nécessaire pour une librairie). Sauf que depuis son installation je ne possédais plus l'IDLE...
    J'ai donc reinstaller Python mais cette fois-ci en 64bits (et j'ai donc retrouver mon IDLE)
    Et là, comble du miracle en lançant mon serveur et mon client depuis l'IDLE : tout fonctionnait. La liste des fichiers et des dossiers contenant des caractères spéciaux s'affichaient normalement.
    Puis....
    Lorsque j'ai essayé de relancer mon serveur (soit directement avec Python.exe soit par l'IDLE) j’obtiens désormais une autre erreur (relative au début du programme).
    Je pose donc l'erreur puis le début de mon serveur:

    Erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Erreur lors de la laison du socket
    Traceback (most recent call last):
      File "C:\Users\Xrh\Desktop\Python\C,S 03\Serveur.py", line 26, in <module>
        sys.exit()
    SystemExit
    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
    25
    26
    27
    28
    29
    30
    #Programmation d'une architecture Client/Serveur
    #Mode: Serveur
    # -*- coding:utf8 -*-
     
     
    try:
        import sys, os, threading, socket, time, platform, subprocess
    except:
        print("Erreur d'importation")
     
    #Classe NULL pour rédiriger les sorties
    class NULL():
        def __init__(self):
            self.content=[]
        def write(self, string):
            self.content.append(string)
    empty_out = NULL()
     
    HOST, PORT, NAME = "127.0.0.1", 50000, "Test n°1"
    SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     
    try:
        SOCK.bind((HOST,PORT))
    except socket.error:
        print("Erreur lors de la laison du socket")
        sys.exit()
    print("Serveur prêt. En attente de requêtes...")
    SOCK.listen(1)
    conn, addr = SOCK.accept()
    print("Client connécté. Adresse IP: %s, Port: %s\n" %(addr[0],addr[1]))
    Après une courte vérification, la ligne incriminée est:
    La liaison du socket ne s'effectue plus.... (décidément les erreurs s'enchainent ).
    Lorsque cela sera réglé, je re-testerai l'affichage du contenu de dossier, mais ce n'est pas possible pour le moment...


    Problème réglé....
    Après une simulation dans la console interactive de Python, celui-ci m'a informé que l'adresse était déjà en cours d'utilisation...
    J'ai donc ouvert mon gestionnaire de tache pour voir sans surprise une 15aines de processus "pythonw.exe".
    Après fermeture de ceux-ci, tout refonctionne (et comme précisé dans le paragraphe barré, mon serveur affiche correctement tout les noms de fichiers et de dossier contenant des caractères spéciaux )

    Maintenant j'ai une dernière question:
    Est-il vraiment impossible de prendre des screenshots avec Python ?
    ImageGrab ne fonctionne pas pour la version 3.
    Et je préfère me passer de l'utilisation de GTK+...
    Je sais que sur un système UNIX c'est assez simple (en émulant la commande import) mais je n'ai rien trouvé de tangible pour Windows et Python 3....

Discussions similaires

  1. Quelle API utiliser pour une appli client/serveur ?
    Par ManusDei dans le forum Plateformes (Java EE, Jakarta EE, Spring) et Serveurs
    Réponses: 2
    Dernier message: 14/10/2010, 08h00
  2. Pb de lenteurs d'une appli client/serveur
    Par Morbo dans le forum Général Java
    Réponses: 0
    Dernier message: 26/03/2010, 20h22
  3. Pb de lenteur d'une appli client/serveur
    Par Morbo dans le forum Documents
    Réponses: 0
    Dernier message: 26/03/2010, 01h21
  4. probleme avec une application client/serveur
    Par filsdugrand dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 28/02/2008, 20h10
  5. Protocole spécifique pour une appli client/serveur
    Par SteelBox dans le forum Développement
    Réponses: 2
    Dernier message: 17/12/2004, 11h20

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