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

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

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

Это изображение может помочь понять, что я хотел реализовать:
Децентрализованный поиск

На картинке выше монитор должен разослать всем свои таблицы. Ключевой вопрос — как получить публичный 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;
}

11

Решение

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

Другие решения

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

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector