Tengo un script en el que, primero, ejecuto un servidor de sockets en un hilo, y cada conexión que reciba, genera su propio hilo. El problema viene cuando intento salirme del programa mediante una excepción KeyboardInterrupt controlada, funciona bien si no ha habido ninguna conexión al socket-servidor, pero si me salgo del programa una vez que he recibido alguna conexión, y, a continuación ejecuto el programa de nuevo, me sale un "socket.error: [Errno 48] Address already in use", como si no hubiese cerrado el socket del servidor correctamente, teniéndome que esperar un rato hasta que se libere el puerto. Tengo controladas dos situaciones una que desde el cliente telnet se pase el comando "quit", con lo que cierro el socket del cliente, y otra cuando se pierde la conexión con el cliente sin introducir el comando "quit" El error solo me lo lanza cuando he salido por medio del "quit".
Aviso que está escrito en python3, y se que hay mejores formas de hacer esto en vez de usar hilos, como el módulo twisted (sin compatibilidad python3) o el asyncore, pero solo tengo planeado recibir un par de conexiones simultáneas por lo que no se generarán muchos hilos. Pongo una versión simplificada del programa, con solo lo básico para ilustrar el problema: #! /usr/bin/env python3 import threading import socket import sys import time class TelnetServer(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.socketserver = socket.socket() self.socketserver.bind(('', 9999)) self.socketserver.listen(5) def run(self): print('Servidor en marcha') while True: socketclient, addr = self.socketserver.accept() client = TelnetClient(socketclient, addr) client.start() def close(self): print('Servidor detenido') class TelnetClient(threading.Thread): def __init__(self, socketclient, addr): threading.Thread.__init__(self) self.socketclient = socketclient self.addr = addr def run(self): print('Conexión: %s:%s' % (self.addr[0], self.addr[1])) while True: try: command, args = self.prompt() except socket.error: self.close() break if command == None: pass elif command == 'quit': self.close() break else: self.send('Comando desconocido\n') def send(self, msg): self.socketclient.send(msg.encode('utf8')) def recv(self): return self.socketclient.recv(1024).decode('utf8')[:-2] def prompt(self): try: self.send('prompt> ') recv_list = self.recv().split() return recv_list[0].lower(), recv_list[1:] except IndexError: return None, [] def close(self): self.socketclient.close() print('Desconexión: %s:%s' % (self.addr[0], self.addr[1])) if __name__ == '__main__': try: telnetserver = TelnetServer() telnetserver.daemon = True telnetserver.start() while True: time.sleep(100) except KeyboardInterrupt: telnetserver.close() sys.exit() _______________________________________________ Python-es mailing list Python-es@python.org http://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/