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 :

Fermeture de socket non désirée


Sujet :

Réseau/Web Python

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut Fermeture de socket non désirée
    Bonjour,

    Je commence la programmation réseau en python, et j'aimerais utiliser le module socketserver, qui aide pour créer un serveur. Mon serveur est un serveur TCP qui reçoit un certain nombre de connexions, et je voudrais qu'il stocke les socket des utilisateurs pour pouvoir ensuite comuniquer avec eux en mode connecté, pas de reconnexion des clients. Voici le code serveur que j'utilise :

    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
    31
    32
    33
    34
    #! /usr/bin/env python3.1
    # -*- coding: utf-8 -*-
     
    import socketserver
    import socket
     
    socks = []
    LEN = 0
     
    class EcouteHandler(socketserver.BaseRequestHandler):
        def handle(self):
     
            # réception du pseudo
            pseudo = self.request.recv(1024).decode("utf8")
     
            socks.append((self.request,pseudo))
            print("socks : ", socks)
     
     
    if __name__ == "__main__":
        HOST, PORT = "localhost", 9999
     
        # Création du serveur d'écoute des joueurs sur le port 9999
        server = socketserver.TCPServer((HOST, PORT), EcouteHandler)
     
        # réception des joueurs
        while LEN < 2 :
            server.handle_request()
            LEN += 1
     
        # fermeture de la socket d'écoute
        server.socket.close()
     
        print(socks)
    Et le 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #! /usr/bin/env python3.1
    # -*- coding: utf-8 -*-
     
    import socket
    import sys
     
    if len(sys.argv) < 2:
        print("usage : %s pseudo" % sys.argv[0])
        sys.exit(1)
     
    HOST, PORT = "localhost", 9999
    pseudo = sys.argv[1]
     
    # Create a socket
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     
    # Connect to server and send data
    sock.connect((HOST, PORT))
    sock.send(bytes(pseudo,"utf8"))
     
    print("Attente de directive")
     
    # Receive data from the server
    while True:
        received = sock.recv(1024) 
        print("reçu : %s, %s" % (len(received), received))
     
    sock.close()
    Le problème est que dès que je sors de la méthode handle() de la classe EcouteHandler, la socket du client en fermée. Elle reste ouverte tant que l'on est dans handle et se ferme juste après. J'ai lu que les sockets sont fermées par le garbage collector mais je ne pense pas qu'il soit appelé ici, puisque je copie mes sockets dans la liste globale. De plus, coté client, je reçois continuellement des "paquets" du serveur qui sont vides (de taille = 0), ce qui indique je crois que la socket a été fermée de l'autre côté (je ne suis pas sur de ça, et je ne comprends pas pourquoi j'en reçois en continu et pas un seul). J'aimerai évidemment que ses sockets restent ouvertes après la sortie de handle (ou au moins comprendre pourquoi elles se ferment).

    Info : j'utilise python 3.1 sous ubuntu karmic, version des dépots.

    Merci d'avance

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 355
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 355
    Points : 36 883
    Points
    36 883
    Par défaut
    Salut
    Relisez l'exemple donné dans la doc... et interrogez vous sur le sens de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()
    - W

  3. #3
    Membre habitué
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Juillet 2005
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2005
    Messages : 147
    Points : 165
    Points
    165
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut
    Relisez l'exemple donné dans la doc... et interrogez vous sur le sens de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()
    - W
    En fait j'ai lu la doc en entier, et au début du chapitre on trouve ceci :
    Finally, call the handle_request() or serve_forever() method of the server object to process one or many requests.
    Mais celà n'a rien à voir avec mon problème, server_forever appelle handle_request. Mon problème était que la socket "request" était fermée à la fin du traitement, ce qui est... normal ! Enfin en tout cas c'est codé comme ça dans la classe socketserver.TCPServer, mais ce n'est écrit nul part dans la doc. J'ai du parcourir le code pour le découvrir.

    Pour rentrer un peu dans les détails, handle_request appelle process_request qui appelle finish_request qui instancie l'objet RequestHandlerClass qui appelle la méthode handle. Ouf, on a fini. Sauf que juste après la méthode finish_request, process_request appelle close_request, qui de base ne fait rien mais est redéfinie dans la classe TCPServer pour fermer la socket request. Et voilà comment on se retrouve avec un comportement décrit nul part dans la doc. Il est certe logique de fermer la socket parce que pour une utilisation classique l'utilisateur ne veut pas la garder ouverte, et ne doit pas la fermer explicitement, mais je pense que ce comportement aurait du être signalé dans la doc.

    Afin de résoudre le problème, j'ai dérivé la classe TCPServer pour réécrire la méthode process_request, afin de ne pas appeler close_request. le code du server posté dans mon premier message devient donc :

    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
    31
    32
    33
    34
    35
    #! /usr/bin/env python3.1
    # -*- coding: utf-8 -*-
     
    import socketserver
    import socket
     
    socks = []
    LEN = 0
     
    class EcouteHandler(socketserver.BaseRequestHandler):
        def handle(self):
     
            # réception du pseudo
            pseudo = self.request.recv(1024).decode("utf8")
     
            socks.append((self.request,pseudo))
            print("socks : ", socks)
     
    if __name__ == "__main__":
        HOST, PORT = "localhost", 9999
     
        class MyTCPServer(socketserver.TCPServer):
            def process_request(self, request, client_address):
                self.finish_request(request, client_address)
     
        server = MyTCPServer((HOST, PORT), EcouteHandler)
     
        while LEN < 2 :
            server.handle_request()
            LEN += 1
     
        # fermeture de la socket d'écoute
        server.socket.close()
     
        print(socks)
    Désolé d'avoir écrit ce pavé, mais j'espère que ça pourra aider les personnes qui rencontreront le même problème.

    @ bientôt

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

Discussions similaires

  1. fermeture de session non désirée
    Par eki27 dans le forum Langage
    Réponses: 4
    Dernier message: 14/10/2012, 08h48
  2. Treeview : fermeture de l'arbre non désirée
    Par Jsh dans le forum ASP.NET
    Réponses: 3
    Dernier message: 22/10/2008, 16h53
  3. Outlook 2007 : Fermeture non désirée
    Par kikouu dans le forum Outlook
    Réponses: 7
    Dernier message: 13/05/2008, 15h09
  4. Suppression en cacsade non désirée
    Par sebgui dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/08/2005, 12h02
  5. [Linux] Probleme de fermeture de Sockets
    Par diefo dans le forum Réseau
    Réponses: 6
    Dernier message: 30/12/2003, 13h10

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