Восстановление из zmq.error.ZMQError: адрес уже используется
Я нажимаю Ctrl-C при запуске соединения PAIR
(неблокирующих клиентских серверов) с ZMQ. Позже, когда я попытался запустить шаблон REQ-REP
(блокирование клиентского подключения к одному серверу), я продолжаю получать ошибку Address already in use
. Я попытался запустить netstat с помощью netstat -ltnp | grep :<my port>
, но это не указывает какой-либо процесс.
Итак, кто именно использует этот адрес?
Также как можно изящно отключить такие подключения сокетов?
Ответы
Ответ 1
Вопрос 1:
Если вы выполняете sudo netstat -ltnp
, в операционной системе типа Linux вы, скорее всего, увидите процесс, владеющий портом. Убейте его с помощью kill -9 <pid>
.
Вопрос 2:
Когда вы выходите из программы, закройте свои сокеты, а затем вызовите zmq_ctx_destroy(). Это разрушает контекст. Подробнее см. http://zguide.zeromq.org/page:all#toc17.
Ответ 2
В этот самый момент:
reboot
Далее:
начните использовать конструкторы инкапсуляции try:
/except:
/finally:
, которые помогут вам предоставить изящный выход из всех распределений zmq, в т.ч. все Socket-ы .close()
и Context .term()
без каких-либо зависших сирот (-ов), утечки памяти, даже в том случае, если какая-либо кнопка паники или необработанное исключение прерывает выполнение вашего кода вместе с потерей ссылок на ваше все еще зависание, сетевое аппаратное обеспечение, экземпляры.
Ответ 3
Иногда другой процесс, использующий zeromq, поддерживает использование порта, а netstat
не указывает, что другое прослушивание процесса (поэтому netstat -lntp
не покажет его), а скорее показывает установленное соединение на порту с тот же хост/порт на обоих концах. После уничтожения этого другого процесса порт теперь доступен для использования.
Причина № 1: У меня это произошло, потому что у меня были порты прослушивания zeromq, настроенные в диапазоне эфемерных портов (на linux, например 32768-61000), которые используются в качестве локальной стороны исходящих подключений, а также мои сервисы необходимо подключиться к другим службам в одном окне. Процент от времени, когда исходящее соединение получает эфемерный порт, который совпадает с портом прослушивания на поле, и вдруг "адрес уже используется". Я просто переместил все прослушивающие порты в сторону эфемерного диапазона портов, и все проблемы "адрес уже используется" исчезли.
Причина № 2: Спекуляция. Когда я столкнулся с аналогичными проблемами с другими сетевыми библиотеками python, процесс нарушения был ранее запущен из процесса прослушивания с использованием подпроцесса или подобного, и возникла проблема с утечкой сокета дочернему устройству обработать; если родительский процесс вышел без закрытия сокета, сокет остался бы в живых и принадлежал дочернему процессу, и хотя дочерний процесс действительно ничего не знал о сокете, он все равно оставался бы таким, чтобы другие процессы не могли используйте его.
Если это проблема, она может быть исправлена путем настройки флагов сокета перед подпроцессом, например. (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)
Или, может быть, есть способ более правильно закрыть сокет в родительском процессе.