ZMQ中发布者的订阅者元数据信息

时间:2013-02-20 03:24:58

标签: c zeromq

我正在使用zmq_socket_monitor服务来使用线程生成方法来监视ZMQ_REP套接字。但据我所知,此服务仅适用于INPROC,而不适用于远程机器。

 My Main code:
    void *ctx = zmq_init (1);
    void *rep = zmq_socket (ctx, ZMQ_REP);
    int rc = zmq_socket_monitor (rep, "inproc://monitor.req", ZMQ_EVENT_ALL);

My Thread Code:
    void rep_socket_monitor (void *ctx)
    {
    zmq_event_t event;
    void *s = zmq_socket (ctx, ZMQ_PAIR);
    rc = zmq_connect (s, "inproc://monitor.req");
    while (true) 
    {
        zmq_msg_t msg;
        rc = zmq_recvmsg (s, &msg, 0);
        memcpy (&event, zmq_msg_data (&msg), sizeof (event));
        switch (event.event)
        {
          //Check for events
        }
    }
    }

如果我检查任何事件,我会得到自己机器的监控地址。 如果某个远程机器客户端尝试连接到我该怎么办? 如何在连接到我正在监控的端口时获取其IP地址。

2 个答案:

答案 0 :(得分:0)

您正在将监视套接字连接到REP套接字,该套接字本身绑定到任何端点,因此没有端点可供外部各方连接。

在您的情况下,例如:

void *ctx = zmq_init (1);
void *rep = zmq_socket (ctx, ZMQ_REP);
int rc = zmq_socket_monitor (rep, "inproc://monitor.req", ZMQ_EVENT_ALL);
// Create thread, check error messages...
...
// Bind the REP socket to your external endpoint
rc = zmq_bind (rep, myExternalEndPoint);

有关如何设置的示例,请查看zmq_socket_monitor API documentation(适用于版本3.2.2)。

注意事项:

  

此初始实现仅支持面向连接(tcp和ipc)传输。

     

ZMQ_EVENT_CONNECTED:已建立连接
  当与远程对等方建立连接时,将触发ZMQ_EVENT_CONNECTED事件。这可以是同步的也可以是异步的。

答案 1 :(得分:0)

从监视器套接字读取的消息有2帧:

  • 事件编号(16位)+事件值(32位)
  • TCP和IPC的受影响端点的名称

文档没有明确说明,但端点是指套接字的本地端点:您绑定的IP /端口。要获取远程端点(连接对等端的ip /端口),首先需要连接文件描述符:ZMQ_EVENT_CONNECTED事件的事件值。然后用获得的fd调用getpeername:

std::string getPeerName(int socketFd) {
    sockaddr_storage sockaddrStore;
    socklen_t len = sizeof(sockaddrStore);

    sockaddrStore.ss_family = AF_UNSPEC;
    getpeername(socketFd, (sockaddr*)&sockaddrStore, &len);

    if (sockaddrStore.ss_family == AF_INET) {
        char addrstr[INET_ADDRSTRLEN];
        sockaddr_in* sockaddrin = (sockaddr_in*)&sockaddrStore;

        inet_ntop(AF_INET, &sockaddrin->sin_addr, addrstr, INET_ADDRSTRLEN);
        return std::string("tcp://") + addrstr;
    }

    return "<unknown>";
}