sor*_*h-r 11 c++ parallel-processing agent zeromq
听起来在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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
但这并不意味着这是一个简单的修复 - 如果盒子有多个 IP/NIC/WAN/LAN 等......当我最近遇到类似的情况时,我强迫调用者明确提供所需的 IP 和端口命令行,然后在连接到其他主机上的其他进程时共享它(在我的例子中,通过 HTTP)。