代码之家  ›  专栏  ›  技术社区  ›  Benp44

ZMQ:连接ZMQ套接字时“资源暂时不可用”

  •  3
  • Benp44  · 技术社区  · 7 年前

    我使用的是ZMQ发布/订阅模式,其中Python程序绑定到一个端口,并使用pyzmq(16.0.2)发布消息,而我的C++程序使用 zsock class 从CZMQ连接为订阅者。

    .奇怪的是, 这个系统在我的开发机器上似乎运行得很好 ,但不在我部署到的目标系统上。

    bool ZmqSocketWrapper::connectSubscriber(string address)
    {
        m_address = address;
        m_pSocket = zsock_new_sub(address.c_str(), "");
    
        int errorCode = zmq_errno();
        if (errorCode != 0)
        {
            printf(zmq_strerror(errorCode));
            return false;
        }
    
        return true;
    }
    

    这称为:

    m_subscriberSocket->connectSubscriber("tcp://127.0.0.1:5555");
    

    m_subscriberSocket->connectSubscriber("tcp://localhost:23232");
    m_subscriberSocket->connectSubscriber("ipc:///tmp/test");
    

    在网上搜索时,似乎大多数人在尝试发送/接收时都有这个问题,所以我在尝试打开套接字时出现这个问题似乎很奇怪。

    其他一些细节:

    • 我的ZMQ发布程序是用pyzmq用Python编写的,运行良好 在同一目标系统上
    • 我看到问题的机器是一个树莓圆周率,如果这是相关的,尽管要记住上面的一点。

    1 回复  |  直到 7 年前
        1
  •  2
  •   user3666197    7 年前

    好消息是纯粹的 pyzmq 场景很好,

    硬件或操作系统相关问题似乎已从故障列表中排除。


    该死的绑定

    第一件事是,
    一些高层实业家为了摆脱原生API而取消了用户端选项。

    CZMQ这样做是因为它假设: 每一个 SUB .connect() ,不离开反向 .bind()/.connect() 之前 设置了套接字连接,这使得分布式系统实现的“高级”绑定更加麻烦。

    接下来是奇怪的事情,代码在一个盒子上运行良好,而在另一个盒子上运行不好。

    我担心的是用户方面的责任 LINGER 归零+ .close() 任何此类创建 附属的 套接字(如果没有适当的异常处理,则不需要发生) zmq.Context() .term() -已取消。这可能会挂起孤儿,导致实际资源(仍)被占用,从而导致 errno 代码11, Resource temporarily unavailable.

    may also like this post.

    bool ZmqSocketWrapper::connectSubscriber(string address)
    {   b_RetFLAG = true;
        m_address = address;
        m_pSocket = zsock_new_sub(address.c_str(), "");
    
        int errorCode = zmq_errno();
        if (errorCode != 0)
        {
            printf(zmq_strerror(errorCode));
            b_RetFLAG = false;
        }
     // -------------------------------------------------------------
        zsock_destroy( &m_pSocket ); // USER's MANDATORY DUTY PRE-RET
     // -------------------------------------------------------------
        return b_RetFLAG;
    }
    

    使用本机API,其中您的代码完全控制阶段。