Efectivamente Sergio, es el mismo comportamiento que yo he observado: la
aplicación cierra el socket, termina y aún así, pasan algunos segundos
para que el puerto quede disponible nuevamente. No me parece que sea un
problema directamente atribuible a tu aplicación, sino más bien a la
forma en que el sistema libera -o registra- que los puertos han sido
liberados. Habría que informarse cómo está implementada la función
'restart' de los servicios de Linux, por ejemplo, porque allí terminan
un servicio y lo reinician tan pronto como es posible. De qué modo
averiguan que ya está disponible el puerto?

Sergio Martín wrote:
Pero al cerrar el socket del servidor (como comento en mi segundo mensaje) ¿no debería liberarse el puerto? Por otro lado ¿como puedo cerrar el hilo si lo tengo en espera de un cliente? ¿Hay alguna otra forma aparte de salir del bucle infinito que tengo?

El 26 de agosto de 2011 15:10, chakalinux <chakali...@gmail.com <mailto:chakali...@gmail.com>> escribió:

    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 <mailto: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 <mailto: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 <mailto: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 <mailto: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/


_______________________________________________
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