Pregunta ¿Cómo cerrar un socket dejado abierto por un programa asesinado?


Tengo una aplicación de Python que abre un socket TCP simple para comunicarse con otra aplicación de Python en un host separado. A veces, el programa puede tener un error o lo mataré directamente, y en cualquier caso, el socket se puede dejar abierto durante un tiempo desconocido.

La próxima vez que voy a ejecutar el programa me sale este error:

socket.error: [Errno 98] Address already in use

Ahora el programa siempre intenta usar el mismo puerto, por lo que parece que todavía está abierto. Comprobé y estoy bastante seguro de que el programa no se está ejecutando en segundo plano y, sin embargo, mi dirección todavía está en uso.

Entonces, ¿cómo puedo cerrar manualmente (o de otra forma) un socket / dirección para que mi programa pueda volver a usarlo de inmediato?

Actualizar

Basado en la respuesta de Mike, revisé socket(7) página y miró SO_REUSEADDR:

SO_REUSEADDR
    Indicates that the rules used in validating addresses supplied in a bind(2) call should
    allow reuse of local addresses.  For AF_INET sockets this means that a socket may bind,
    except when there is an active listening socket bound to the address.  When the listen‐
    ing  socket is bound to INADDR_ANY with a specific port then it is not possible to bind
    to this port for any local address.  Argument is an integer boolean flag.

32
2018-05-03 14:14


origen


Respuestas:


Suponga que su socket se llama s... debes establecer socket.SO_REUSEADDR en el socket del servidor antes de enlazar a una interfaz ... esto le permitirá reiniciar inmediatamente un servidor TCP ...

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))

33
2018-05-03 15:00



Es posible que desee intentar usar Twisted para su red. Mike dio la respuesta correcta de bajo nivel, SO_REUSEADDR, pero no mencionó que esta no es una muy buena opción para configurar en Windows. Este es el tipo de cosas que Twisted cuida automáticamente de usted. Hay muchos, muchos otros ejemplos de este tipo de detalles aburridos de bajo nivel a los que tiene que prestar atención cuando usa el módulo de socket directamente, pero que puede olvidar si usa una biblioteca de nivel superior como Twisted.


10
2018-05-04 01:04



Estás confundiendo tomas de corriente, conexiones y puertos. Los sockets son puntos finales de las conexiones, que a su vez son 5-tuplas {protocolo, local-ip, local-port, remote-ip, remote-port}. El SO ha cerrado el zócalo del programa destruido y lo mismo ocurre con la conexión. La única reliquia de la conexión es el zócalo del par y el puerto correspondiente en el host par. Entonces, lo que realmente debería preguntar es cómo reutilizar el local Puerto. A lo que la respuesta es SO_REUSEADDR según las otras respuestas.


3
2018-05-04 10:33