我正在使用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>";
}