听起来在ZeroMQ中使用传统UNIX套接字的套接字是没有意义的。我基于对ZeroMQ的错误感知设计了一种用于分布式搜索算法的架构。在我的程序中,有一个代理负责监视其他代理并收集他们的数据。在PULL-PUSH或PUB-SUB模式之后,将在代理之间传输实际数据。每个代理都有一个PULL套接字监听传入的消息。每条消息都包含一个ID号,用于指定发件人标识。
在初始化阶段,监视器应该监听其REP套接字。每个代理将连接到监视器的着名REP套接字并自我介绍(发送他的ID号和代理正在侦听的端口号)。监视器将有关代理的所有数据存储在三个字段的记录中:<ID, IP, port>
。 (这是我在ZMQ遇到问题的地方。)当某些代理程序准备就绪时,监视器会将所有数据(每个代理程序的<IP,ID,port>
)发送给所有代理程序。最后一步是通过代理和监视器之间的PUB-SUB模式完成的。
此图片可能有助于了解我的意图:
在上图中,显示器应该将它的表发送给每个人。关键问题是如何以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;
}
答案 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)
为什么不将其作为有效载荷的一部分发送出去?