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/

Responder a