Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 08/03/2007, à 20:31

Gari

[Résolu]python + fonction accept (socket)

Salut,

je suis tombé sur un os, et j'ai l'impression que je devrais connaître la solution mais j'y arrive pas tongue

donc voilà :
- j'ai un thread serveur qui fonctionne avec la fonction accept (il attend les connexions de clients).
- J'ai un autre thread qui, à un moment donné, aimerait donner l'ordre au premier thread de cesser d'attendre des connexions. 

Mon problème : comment quitter la fonction accept sur ordre d'un autre thread ? Comment quitter la fonction accept tout court, d'ailleurs ? Y-a-t-il possibilité de mettre un timeout ?
Si *vraiment* ce n'est pas possible, est-il possible de tuer le thread serveur proprement ?

Merci smile

[EDIT] Suite à la remarque de mr404, changement du titre et du corps du message en remplaçant "listen" par "accept".

Dernière modification par Gari (Le 12/03/2007, à 12:09)

Hors ligne

#2 Le 10/03/2007, à 00:22

mr404

Re : [Résolu]python + fonction accept (socket)

Salut,
Je pense que j'ai eu le même problème, es-tu sur que c'est le listen qui bloque et pas l'accept?
Sinon tu peux mettre ton thread en deamon cela permettra au programme de ce fermer même si ce thread n'a pas fini, mais n'oublie pas de bien fermer tous le reste, en particulier les sockets.

Pour le timeout il faut utiliser une class qui n'est pas standard mais dans ton cas le timeout ne changera rien car c'est pas la connection qui ne se ferme pas.

Hors ligne

#3 Le 11/03/2007, à 19:46

Gari

Re : [Résolu]python + fonction accept (socket)

Heu oui effectivement, tu fais bien de le dire, c'est bien le accept le problème, pas le listen (j'ai écris un peu vite).

Mon problème est le suivant :
- un thread serveur en attente de connexion (on ne sait combien, ni quand elles arrivent).
- un thread client qui peut, à tout moment, décider de ne plus attendre de connexion. Il faut donc prévenir le thread serveur (ou le tuer).

=> C'est dans l'objectif de faire un petit jeu réseau, dans lequel on attend des joueurs et où on peut lancer le jeu à tout moment (donc, en cessant d'attendre des joueurs).

Je ne crois pas que le lancement en daemon change quoi que ce soit...

Hors ligne

#4 Le 12/03/2007, à 12:06

Gari

Re : [Résolu]python + fonction accept (socket)

Je viens de trouver la méthode pour résoudre le problème. Cette méthode fonctionne sous Linux et sous Windows. Je ne sais pas sous MacOS, mais je ne pense pas qu'il y ait de problèmes.

il s'agit d'utiliser le module "timeoutsocket" qui n'est pas fourni en standard avec python.
On peut le récupérer là : http://www.timo-tasi.org/python/timeoutsocket.py

Un exemple de code que j'ai écris pour mettre en avant le fonctionnement de ce module :

# -*- coding: utf-8 -*-

"""Ce module a pour but de tester les socket et les timeout sur socket.
Nous mettons en oeuvre le serveur et le client dans des threads,
le corps principal ayant pour unique objectif de lancer les deux."""

import threading
import time
import timeoutsocket
import socket
import os
import signal


HOST = 'localhost'
PORT = 50007
AttendreClient = True


class ThreadServeur(threading.Thread):
   def run(self):
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.bind((HOST, PORT))
      s.listen(1)
      while 1:
         try:
            conn, addr = s.accept()
         except timeoutsocket.Timeout:
            print "Timeout atteint au niveau de accept"
            if not AttendreClient:
               print "Le serveur ne doit plus attendre de client : on quitte"
               break
         except:
            print "Erreur de accept"
            break
         else:
            print 'Connected by', addr
            data = conn.recv(1024)
            if not data:
               break
            conn.send(data)
      conn.close()

class ThreadClient(threading.Thread):
   def run(self):
      time.sleep(1)
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      s.connect((HOST, PORT))
      s.send('Hello, world')
      data = s.recv(1024)
      s.close()
      print 'Received', repr(data)


timeoutsocket.setDefaultSocketTimeout(5)
threadserveur = ThreadServeur()
threadclient  = ThreadClient()
threadserveur.start()
threadclient.start()
print "Création des threads effectuée. On attend la mort du client."
threadclient.join()
print "Fin des clients. On attend 10 secondes pour voir si le timeout fonctionne."
time.sleep(10)
print "On demande la mort du serveur (peut s'écouler quelques secondes...)."
AttendreClient = False
threadserveur.join()
print "Le serveur est mort, on meurt à notre tour."

En espérant que cela servira à d'autres smile

Dernière modification par Gari (Le 12/03/2007, à 12:11)

Hors ligne