2010-10-25 4 views
2

Je rencontre des problèmes lors de la détection d'une socket rompue en cas d'exception de tuyau cassé. Voir le code ci-dessous pour un exemple:interception d'une socket rompue en python

Serveur:

import errno, select, socket, time, SocketServer 

class MetaServer(object): 
    def __init__(self): 
     self.server = Server(None, Handler, bind_and_activate=False) 
    def run(self, sock, addr): 
     rfile = sock.makefile('rb', 1) 
     self.server.process_request(sock, addr) 
     while 1: 
      r, _, _ = select.select([rfile], [], [], 1.0) 
      if r: 
       print 'Got %s' % rfile.readline() 
      else: 
       print 'nothing to read' 

class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 
    allow_reuse_address = True 
    daemon_threads = True 

class Handler(SocketServer.StreamRequestHandler): 
    def handle(self): 
     print 'connected!' 
     try: 
      while 1: 
       self.wfile.write('testing...') 
       time.sleep(1) 
     except socket.error as e: 
      if e.errno == errno.EPIPE: 
       print 'Broken pipe!' 
     self.finish() 
     self.request.close() 

if __name__ == '__main__': 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.bind(('127.0.0.1', 8081)) 
    s.listen(5) 
    ms = MetaServer() 
    while 1: 
     client, address = s.accept() 
     ms.run(client, address) 

Le client:

import select, socket 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect(('127.0.0.1', 8081)) 
while 1: 
    r, _, _ = select.select([s], [], [], 1.0) 
    if not r: 
     continue 
    msg = s.recv(1024) 
    print 'Got %s' % (msg,) 

Maintenant, si je lance le serveur et le client, tout va bien, et je reçois un "Rien n'est lu" message chaque seconde. Dès que je CTRL-C sur le client, le serveur devient fou et commence à "lire" à partir de ce qui devrait être une socket busted, en jetant beaucoup de messages "Got".

Y a-t-il un moyen de détecter ce socket cassé dans la fonction MetaServer.run() pour éviter le comportement mentionné ci-dessus?

+0

Vous pouvez le détecter en 'select' disant que les données sont prêtes mais' read'/'readline' en retournant une chaîne vide, n'est-ce pas? – adw

+0

Voilà ce que je me dis qui se passe. – user464164

Répondre

3

Oui, c'est quelque chose qui n'est pas vraiment dans la documentation mais un comportement Un * x ancien: Vous devez abandonner quand vous obtenez une chaîne vide.

+0

oh, c'est difficile. Merci! – user464164