En la interrupcion KeyboardInterrupt tienes que cerrar los hilos para que no se te quede el mismo en CLOSE_WAIT que en ciertos casos puede durar bastante en liberarse.
De todas maneras yo te recomiendo que uses la librería select o asyncore para manejar socket's, intenta evitar cuando puedas sockets y threading El 26 de agosto de 2011 02:21, Sergio Martín <sergiomart...@gmail.com>escribió: > Comentar que aunque añada la línea: > self.socketserver.close() > en el método close() de la clase TelnetServer el resultado es el mismo. > > El día 26 de agosto de 2011 02:17, Sergio Martín > <sergiomart...@gmail.com> escribió: > > 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/ >
_______________________________________________ Python-es mailing list Python-es@python.org http://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/