zmq.error.ZMQError:无法分配请求的地址

时间:2018-05-19 06:51:28

标签: amazon-ec2 zeromq pyzmq

我在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 codeadded 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。

如何解决这个不便?

2 个答案:

答案 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(在同一端口上)后,它起作用了。