zmq.error.ZMQError: Невозможно назначить запрошенный адрес - PullRequest
0 голосов
/ 19 мая 2018

У меня есть следующая схема ZMQ для публикации и публикации на компьютере Amazon EC2:

Я работаю с публичным IP-адресом моего компьютера EC2 Amazon.

Я пытаюсь отправить данные черезСокет ZMQ PUSH со стороны клиента до стороны сервера сокетов ZMQ PULL, который выглядит следующим образом:

import zmq
from zmq.log.handlers import PUBHandler
import logging
# from zmq.asyncio import Context

def main():
    ctx = zmq.Context()
    publisher = ctx.socket(zmq.PUB)
    # publisher.bind("tcp://*:5557")
    publisher.bind("tcp://54.89.25.43:5557")

    handler = PUBHandler(publisher)
    logger = logging.getLogger()
    logger.addHandler(handler)

    print("Network Manager CNVSS Broker listening")

    collector = ctx.socket(zmq.PULL)
    # collector.bind("tcp://*:5558")
    collector.bind("tcp://54.89.25.43:5558")

    while True:
        message = collector.recv()
        print("Publishing update %s" % message)
        publisher.send(message)

if __name__ == '__main__':
    main()

Но когда я выполняю этот сценарий,Я получаю эту ошибку:

(cnvss_nm) ubuntu@ip-172-31-55-72:~/cnvss_nm$ python pull_pub-nm.py 
Traceback (most recent call last):
  File "pull_pub-nm.py", line 28, in <module>
    main()
  File "pull_pub-nm.py", line 10, in main
    publisher.bind("tcp://54.89.25.43:5557")
  File "zmq/backend/cython/socket.pyx", line 547, in zmq.backend.cython.socket.Socket.bind
  File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc
zmq.error.ZMQError: Cannot assign requested address
(cnvss_nm) ubuntu@ip-172-31-55-72:~/cnvss_nm$ 

Я изменил свой IP-адрес на publisher.bind("tcp://*:5557") и collector.bind("tcp://*:5558") на стороне сервера, и мой скрипт выполняется:

(cnvss_nm) ubuntu@ip-x-x-x-x:~/cnvss_nm$ python pull_pub-nm.py 
Network Manager CNVSS Broker listening

Но из моего кода стороны клиента ( добавлено недавно ) отправляются любые данные.

#include <zmq.hpp>
#include <zmq.h>
#include <iostream>
#include "zhelpers.hpp"

using namespace std;

int main(int argc, char *argv[])
{
    zmq::context_t context(1);
    /*
    std::cout << "Sending message to NM Server…\n" << std::endl; */

    zmq::socket_t subscriber(context, ZMQ_SUB);
    subscriber.connect("tcp://localhost:5557");
    subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);

    zmq::socket_t sender(context, ZMQ_PUSH);
    sender.connect("tcp://localhost:5558");

    string firstMessage = "Hola, soy el cliente 1";

    while (1)
    {
        //  Wait for next request from client
        std::string string = s_recv(subscriber);

        std::cout << "Received request: " << string << std::endl;

        // Do some 'work'
        // sleep(1);

        //  Send reply back to client
        // zmq::message_t message(firstMessage.size() + 1);

        // Cualquiera de los dos se puede
        // memcpy(message.data(), firstMessage.c_str(), firstMessage.size() + 1);
        // s_send(sender, "Hola soy un responder 1");

        // sender.send(message);
    }
}

Я думаю, что мое неудобствона конфигурации сети моего компьютера EC2 или на пути настройки IP-адреса сервера.

Когда я тестирую клиентов и сервер локально, все это работает отлично.

Есть ли возможностьвыполнять некоторые операции пересылки или NAT на моем компьютере EC2?

Мои клиенты не достигают сервера.

Iимеют ли группы безопасности правила вышеупомянутых портов 5557 и 5558.

Как устранить это неудобство?

Ответы [ 2 ]

0 голосов
/ 30 марта 2019

У меня была похожая ситуация, когда я использовал ZMQ на EC2 и получал «Невозможно назначить запрошенный адрес».Я также использовал Elastic IP, как предложено в ответе, но у меня это не сработало.Оказалось, что в EC2 отправляющая сторона (ZMQ.PUSH) должна привязываться к частному IP, а не к общему, в то время как принимающая сторона должна привязываться к общему IP, поэтому попытка связать сервер с Elastic IP вызвалаОшибка.После того, как я изменил его для привязки стороны сервера ZMQ.PUSH к частному IP, а клиента ZMQ.PULL к Elastic IP (на том же порту), он заработал.

0 голосов
/ 19 мая 2018

Как решить это неудобство?

1)
Если есть сомнения по поводу EC2сначала попытайтесь проверить обратный .bind() / .connect(), чтобы назначения локального хоста на стороне EC2 вышли из игры, и ваше доказательство подключения к известному IP-адресу не будет зависеть от EC2-настройки стороны.

2)
Далее, учитывая отсутствие подробностей о клиентской части MCVE, возможно, я неправильно понял идею сценария, так что терпите меня- с тех пор доступны только эти совместимые масштабируемые формальные коммуникационные архетипы ZeroMQ сокетов , вплоть до API v4.2.x в 2018 / Q2:

{ PUB:  [  SUB,
          XSUB,
          None
          ],
  PULL: [ PUSH,
          None
          ],
  ...
  }

3)
Существует хорошая инженерная практика, позволяющая не допускать возникновения необработанных исключений, тем более, если Context() -инстанция может все еще обладать IP: PORT # (b) заблокированным ресурсом (иногда даже за пределами питона)завершение процесса (много инцидентов с моей собственной наивностью и этимпуть тупиковых экспериментов в моей прошлой мрачной истории: o))

Каждый шаг в настройке инфраструктуры должен быть заключен в синтаксический раздел обработки ошибок, лучше всего включающий раздел finally:, где до сих пор созданные ресурсы будут время от времениИзящно разбираться в тех случаях, когда возникают исключения.Таким образом, ваш код предотвратит навсегда зависших сирот, у которых есть только возможность перезагрузить платформу, чтобы избавиться от этих, иначе невозможно спасти заложников.


Проблема решена,
окончательное резюме:

Первоначально указанная проблема (диагностированная на этапе .bind() / .connect()), как было показано ранее, была связана с отображением IP-адреса экземпляра Amazon EC2 в качестве термина, необходимого для любого транспорта.Настройка конечной точки класса, localhost:port#

camdebu 1 ноября 2012 17:07 объяснил все необходимые шаги:
Установите Elastic IP на ваш EC2 isntance.Тогда у вас будет статический IP-адрес.Elastic IP не требует затрат, если он указывает на экземпляр EC2.

После этого у вас не должно возникнуть проблем с подключением к вашему новому IP-адресу и порту при условии, что ваша безопасностьгруппа настроена правильно.-Cam-

  • Проверьте правило группы безопасности.Убедитесь, что вы разрешаете порту взаимодействовать извне.(Включите все TCP и проверьте). [добавлено Yesu Jeya Bensh.P]

Недавно опубликованный код клиента, но показывает другую проблему, взаимный блок ,генерируется не взаимодействующим zmq::socket_t sender( context, ZMQ_PUSH ), который фактически никогда не отправляет отдельное сообщение.

Учитывая, что клиент переходит в while(1) -loop какопубликовано выше, связанный одноранговый узел непреднамеренно войдет в нераспространенное заблокированное состояние внутри созданного Python main(), так как:

def main():
    ...
    collector = ctx.socket( zmq.PULL )
    #ollector.bind( "tcp://*:5558"           )
    collector.bind( "tcp://54.89.25.43:5558" )

    while True:
        message = collector.recv()           # THIS SLOC WILL BLOCK FOREVER HERE,
        ...                                  #      GIVEN <sender> NEVER SENDS...

, так что нужно быть более внимательным, чтобы сделать поток событийдостаточно крепкий, чтобы никогда не попасть в этот или подобный неразрушимый взаимный блок.

...