c-ZMQ中发布者的订阅服务器元数据信息



我正在使用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地址。

您正在将监控套接字连接到REP套接字,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_monitorneneneba API文档(用于版本3.2.2),以获取如何设置它的示例。

需要注意的事项:

在这个初始实现中,只支持面向连接的(tcp和ipc)传输。

ZMQ_EVENT_CONNECTED:已建立连接
ZMQ_EVENT_CONNECTED事件在与远程对等方建立连接时触发。这种情况可以同步发生,也可以异步发生。

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

  • 事件编号(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>";
}

最新更新