如何在ZeroMQ的REQ-REP模式中获取请求者的公共IP?

时间:2013-05-24 14:44:38

标签: c++ parallel-processing zeromq agent

听起来在ZeroMQ中使用传统UNIX套接字的套接字是没有意义的。我基于对ZeroMQ的错误感知设计了一种用于分布式搜索算法的架构。在我的程序中,有一个代理负责监视其他代理并收集他们的数据。在PULL-PUSH或PUB-SUB模式之后,将在代理之间传输实际数据。每个代理都有一个PULL套接字监听传入的消息。每条消息都包含一个ID号,用于指定发件人标识。

在初始化阶段,监视器应该监听其REP套接字。每个代理将连接到监视器的着名REP套接字并自我介绍(发送他的ID号和代理正在侦听的端口号)。监视器将有关代理的所有数据存储在三个字段的记录中:<ID, IP, port>。 (这是我在ZMQ遇到问题的地方。)当某些代理程序准备就绪时,监视器会将所有数据(每个代理程序的<IP,ID,port>)发送给所有代理程序。最后一步是通过代理和监视器之间的PUB-SUB模式完成的。

此图片可能有助于了解我的意图: De-centralized Search

在上图中,显示器应该将它的表发送给每个人。关键问题是如何以REQ-REP模式获取请求者(任何代理)的公共IP地址?所有代理都绑定到其本地主机(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;
}

2 个答案:

答案 0 :(得分:2)

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 / NIC / WAN / LAN等等......当我最近遇到类似的情况时,我强迫调用者明确提供所需的IP和命令行上的端口,然后在连接到其他主机上的其他进程时共享它(在我的例子中,通过HTTP)。

答案 1 :(得分:0)

为什么不将其作为有效载荷的一部分发送出去?