Recuperación de zmq.error.ZMQError: la dirección ya está en uso

Presioné Ctrl-C mientras ejecutaba una conexión de patrón PAIR (servidores de cliente sin locking) con ZMQ. Más tarde, cuando intenté ejecutar el patrón REQ-REP (bloqueando la conexión de un solo servidor del cliente), sigo obteniendo el error de Address already in use . He intentado ejecutar netstat con netstat -ltnp | grep : netstat -ltnp | grep : pero eso no enumera ningún proceso.

Entonces, ¿quién está usando exactamente esta dirección?

También, ¿cómo se pueden cerrar con gracia conexiones de socket como éstas?

Pregunta 1:

Si lo hace sudo netstat -ltnp , en un sistema operativo tipo Linux, lo más probable es que vea el proceso que posee el puerto. Mátalo con kill -9 .

Pregunta 2:

Cuando salga del progtwig, cierre los sockets y luego llame a zmq_ctx_destroy (). Esto destruye el contexto. Consulte http://zguide.zeromq.org/page:all#toc17 para obtener más información.

En este preciso momento:

 reboot 

Siguiente:

comience a usar try: / except: / finally: encapsulation constructors, que le ayudará a otorgar una salida elegante de todas las asignaciones de zmq, incl. todos los Socket -s ‘ .close() y .Term() Context sin ningún huérfano (s) colgante / s una (s) pérdida (s) de memoria, incluso en caso de que algún botón de pánico o excepción no controlada interrumpa la ejecución del código por completo con la pérdida de referencias a su stil hanging, red-hardware enlazado, instancias.

A veces, otro proceso de uso de zeromq mantiene el puerto en uso, y netstat no indica que el otro proceso netstat -lntp escuchando (por lo tanto, netstat -lntp no lo mostrará), sino que muestra una conexión establecida en el puerto con el mismo host / puerto en ambos extremos Después de matar ese otro proceso, el puerto ya está disponible para su uso.

Razón # 1: Esto sucedió porque tuve los puertos de escucha zeromq configurados en el rango de puertos efímeros (en Linux, por ejemplo, 32768-61000) que se utilizan como el lado local de las conexiones salientes, y mis servicios deben conectarse A otros servicios en la misma caja. Un porcentaje del tiempo que una conexión saliente obtiene un puerto efímero que es lo mismo que un puerto de escucha en la caja, y de repente “dirección ya en uso”. Acabo de mover todos los puertos de escucha fuera del camino del rango de puertos efímeros y todos los problemas de “direcciones en uso” desaparecieron.

Razón # 2: Especulación: cuando me he encontrado con problemas similares con otras bibliotecas de la red de Python, el proceso ofensivo se inició previamente desde el proceso de escucha con subproceso o similar, y hubo un problema con la fuga del socket al proceso hijo; Si el proceso principal se cerrara sin cerrar el socket, el socket quedaría vivo y pertenecería al proceso secundario, y aunque el proceso secundario realmente no sabía nada sobre el socket, se mantendría así que otros procesos no podrían utilízalo

Si ese es el problema, podría solucionarse ajustando las banderas del socket antes del subproceso, por ejemplo (específico de Unix):

 fd = sock.get(zmq.FD) old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) 

O tal vez hay una manera de cerrar más adecuadamente el socket en el proceso padre.