我在Amazon EC2计算机上有以下pull-publisher ZMQ架构:
我正在处理我的EC2亚马逊机器的公共IP地址。
我正在尝试通过ZMQ PUSH
套接字从客户端向ZMQ PULL
套接字服务器端发送数据,这是:< / p>
import zmq
from zmq.log.handlers import PUBHandler
import logging
# from zmq.asyncio import Context
def main():
ctx = zmq.Context()
publisher = ctx.socket(zmq.PUB)
# publisher.bind("tcp://*:5557")
publisher.bind("tcp://54.89.25.43:5557")
handler = PUBHandler(publisher)
logger = logging.getLogger()
logger.addHandler(handler)
print("Network Manager CNVSS Broker listening")
collector = ctx.socket(zmq.PULL)
# collector.bind("tcp://*:5558")
collector.bind("tcp://54.89.25.43:5558")
while True:
message = collector.recv()
print("Publishing update %s" % message)
publisher.send(message)
if __name__ == '__main__':
main()
但是当我执行此脚本时,我收到此错误:
(cnvss_nm) ubuntu@ip-172-31-55-72:~/cnvss_nm$ python pull_pub-nm.py
Traceback (most recent call last):
File "pull_pub-nm.py", line 28, in <module>
main()
File "pull_pub-nm.py", line 10, in main
publisher.bind("tcp://54.89.25.43:5557")
File "zmq/backend/cython/socket.pyx", line 547, in zmq.backend.cython.socket.Socket.bind
File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc
zmq.error.ZMQError: Cannot assign requested address
(cnvss_nm) ubuntu@ip-172-31-55-72:~/cnvss_nm$
我已将服务器端的IP地址更改为publisher.bind("tcp://*:5557")
和collector.bind("tcp://*:5558")
,我的脚本正在运行:
(cnvss_nm) ubuntu@ip-x-x-x-x:~/cnvss_nm$ python pull_pub-nm.py
Network Manager CNVSS Broker listening
但是从我的client-side code(added recently)开始,会发送任何数据。
#include <zmq.hpp>
#include <zmq.h>
#include <iostream>
#include "zhelpers.hpp"
using namespace std;
int main(int argc, char *argv[])
{
zmq::context_t context(1);
/*
std::cout << "Sending message to NM Server…\n" << std::endl; */
zmq::socket_t subscriber(context, ZMQ_SUB);
subscriber.connect("tcp://localhost:5557");
subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);
zmq::socket_t sender(context, ZMQ_PUSH);
sender.connect("tcp://localhost:5558");
string firstMessage = "Hola, soy el cliente 1";
while (1)
{
// Wait for next request from client
std::string string = s_recv(subscriber);
std::cout << "Received request: " << string << std::endl;
// Do some 'work'
// sleep(1);
// Send reply back to client
// zmq::message_t message(firstMessage.size() + 1);
// Cualquiera de los dos se puede
// memcpy(message.data(), firstMessage.c_str(), firstMessage.size() + 1);
// s_send(sender, "Hola soy un responder 1");
// sender.send(message);
}
}
我认为我不方便的是我的EC2机器网络配置或设置服务器IP地址的方式。
当我在本地测试客户端和服务器时,它完全可以正常工作。
是否有可能在我的EC2机器上执行某些转发或NAT操作?
我的客户无法访问服务器。
我有安全组规则上面提到的端口5557和5558。
如何解决这个不便?
答案 0 :(得分:1)
如何解决这种不便?
1)
如果对EC2地址有疑问,请首先尝试测试反向的 .bind() / .connect()
,以便EC2端本地主机地址分配不在游戏中,并且您对已知IP地址的连接证明将不依赖于EC2端设置。
2)
接下来,由于没有关于MCVE的客户端部分的详细信息,我可能已经深入了解了这个场景,所以请耐心等待 - 只有这些兼容的ZeroMQ可扩展形式通信原型套接字'从那时起匹配,直到2018年/ Q2的API v4.2.x:
{ PUB: [ SUB,
XSUB,
None
],
PULL: [ PUSH,
None
],
...
}
3)
有一个很好的工程实践,不要让未处理的异常发生,如果Context()
- 实例可能仍然拥有IP,那就越多:PORT# (b)锁定资源(有时甚至超出了python进程终止(许多事件与我自己的天真,这种方式在我过去的黑暗历史中陷入僵局的实验:o))
基础架构设置中的每个步骤都应该包含在错误处理语法子句中,最好包括finally:
部分,在这种情况下,当异常(s)时,到目前为止创建的资源偶尔会以优雅的方式被拆除。弹出来。通过这种方式,您的代码将阻止永久挂起的孤儿,它只能重新启动平台,以便摆脱这些,否则无法挽救人质。
如前所述,最初指出的问题(在.bind() / .connect()
阶段诊断出)与Amazon EC2实例IP地址映射相关,作为任何传输类端点设置所需的术语, { {1}} 强>
camdebu on Nov 1, 2012 5:07 PM解释了所需的所有步骤:
为您的EC2意图设置弹性IP。然后,您将拥有一个静态IP地址。只要您指向EC2实例,弹性IP就没有成本。只要您的安全组设置正确,您就可以连接到新的IP地址和端口。 -Cam - 子>
- 检查您的安全组规则。确保允许端口从实例外部进行通信。 (启用所有TCP和检查)。 [添加了Yesu Jeya Bensh.P] 子>
最近发布的客户端代码,但显示了另一个问题,相互阻止,由非合作 localhost:port#
{{1}生成,实际上从不发送任何消息。
鉴于客户端进入上面发布的zmq::socket_t
循环,关联的对等方将无意中进入python制作的sender( context, ZMQ_PUSH )
内的不可避免的阻塞状态,因为:
while(1)
因此需要更加小心,以便使事件流动足够强大,不要陷入这种或类似的不可救药的相互阻滞。
答案 1 :(得分:1)
我有类似的情况,我在EC2上使用ZMQ并收到“无法分配请求的地址”。我也按照答案中的建议使用弹性IP,但对我而言不起作用。事实证明,在EC2上,发送方(ZMQ.PUSH)需要绑定到私有IP而不是公共,而接收方需要绑定到公共IP,因此尝试将服务器绑定到Elastic IP错误。在我将其更改为将服务器ZMQ.PUSH端绑定到专用IP并将客户端ZMQ.PULL绑定到弹性IP(在同一端口上)后,它起作用了。