Подтвердить что ты не робот

Как получить общедоступный IP-адрес реквестера в шаблоне REQ-REP для ZeroMQ?

Похоже, в ZeroMQ нет смысла работать с сокетами в терминах традиционных UNIX-сокетов. Я разработал архитектуру для алгоритма распределенного поиска, основанного на неправильном восприятии ZeroMQ. В моей программе есть агент, ответственный за мониторинг других агентов и сбор их данных. Реальные данные будут передаваться между агентами, следуя шаблону PULL-PUSH или PUB-SUB. Каждый агент имеет гнездо PULL, которое прослушивает входящие сообщения. Каждое сообщение содержит идентификационный номер, который указывает идентификацию отправителя.

На этапе инициализации монитор должен прослушивать его сокет REP. Каждый агент будет подключаться к монитору известного сокета REP и вводить его (отправляет свой идентификационный номер и номер порта, который прослушивает агент). Монитор хранит все данные об агентах в записях трех полей: <ID, IP, port>. (Здесь у меня проблема с ZMQ.) Когда определенное количество агентов становится готовым, монитор отправляет все данные (каждый агент <IP,ID,port>) всем агентам. Последний шаг выполняется с помощью шаблона PUB-SUB между агентами и монитором.

Это изображение может помочь понять, что я хотел реализовать: De-centralized Search

На приведенном выше рисунке монитор должен отправить таблицу всем. Ключевой вопрос: как получить общедоступный IP-адрес запрашивающего (любого агента) в шаблоне REQ-REP? Все агенты привязываются к локальному хосту (127.0.0.1). Они должны распределяться по произвольному количеству хостов. Поэтому AFAIK им нужно знать публичный IP-адрес друг друга.

В случае отсутствия решения любая помощь по перепроектированию архитектуры является подходящей.

Обновление

Решением кандидата, о котором я могу думать, является изменение каждого агента для привязки к его/ее публичному IP вместо localhost. Если есть волшебный способ получения общедоступного IP-адреса, любой агент может отправить свой адрес на монитор.

Второе обновление

В настоящее время агент получает свой общедоступный IP-адрес и отправляет его через сообщение на сервер:

std::string AIT::ABT_Socket::getIP() {
    std::string address = "";
    FILE * fp = popen("ifconfig", "r");
    if (fp) {
        char *p = NULL, *e;
        size_t n;
        while ((getline(&p, &n, fp) > 0) && p) {
            if (p = strstr(p, "inet addr:")) {
                p += 10;
                if (e = strchr(p, ' ')) {
                    *e = '\0';
                    return std::string(p);
                    address = std::string(p);

                }
            }
        }
    }
    pclose(fp);
    return address;
}
4b9b3361

Ответ 1

boost может определить ваш IP-адрес переносимым образом следующим образом:

tcp::resolver resolver(io_service);
tcp::resolver::query query(boost::asio::ip::host_name(), "");
tcp::resolver::iterator iter = resolver.resolve(query);
tcp::resolver::iterator end; // End marker.
while (iter != end)
{
    tcp::endpoint ep = *iter++;
    std::cout << ep << std::endl;
}

Но это не значит, что это простое исправление - что, если в ящике есть несколько IP-адресов/сетевых адаптеров /WAN/LAN и т.д.... Когда у меня была похожая ситуация в последнее время, я заставил вызывающего явно указать желаемый IP-адрес и порт в командной строке, а затем поделился им при подключении к другим процессам на других хостах (в моем случае, через HTTP).

Ответ 2

Почему бы вам просто не отправить его как часть полезной нагрузки?