[zeromq-dev] SocketMonitor receives connection events after close event
Auer, Jens
jens.auer at cgi.com
Tue Sep 13 10:55:12 CEST 2016
Hi,
I am using a socket monitor to generate logging output for socket state events such as connection retries and disconnects. It basically works fine, but I am seeing connection retry events after receiving a close event. Is that correct? It feels strange that the socket tries to reconnect after it has been closed.
I have modified the example from the man page to be closer to my case. It basically opens a REQ socket, sends a message and then zmq_polls for an answer for 500ms. After that, the socket is closed and the monitor is read in a loop until ZMQ_EVENT_MONITOR_STOPPED is received. The events are logged to stdout as hex values:
./monitor
event: 2
event: 80
event: 4
event: 2
event: 80
event: 4
event: 2
event: 80
event: 4
event: 2
event: 80
event: 4
event: 400
>From what I see, the monitor receives multiple close events (80) and after the close event still connection retried (4) and connect delayed (2) events. Finally it receives the monitor close event. Is this expected?
The test code is:
#include <zmq.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
// Read one event off the monitor socket; return value and address
// by reference, if not null, and event number by value. Returns -1
// in case of error.
static int
get_monitor_event (void *monitor, int *value, char **address)
{
// First frame in message contains event number and value
zmq_msg_t msg;
zmq_msg_init (&msg);
if (zmq_msg_recv (&msg, monitor, 0) == -1)
return -1; // Interrupted, presumably
assert (zmq_msg_more (&msg));
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
uint16_t event = *(uint16_t *) (data);
if (value)
*value = *(uint32_t *) (data + 2);
// Second frame in message contains event address
zmq_msg_init (&msg);
if (zmq_msg_recv (&msg, monitor, 0) == -1)
return -1; // Interrupted, presumably
assert (!zmq_msg_more (&msg));
if (address) {
uint8_t *data = (uint8_t *) zmq_msg_data (&msg);
size_t size = zmq_msg_size (&msg);
*address = (char *) malloc (size + 1);
memcpy (*address, data, size);
(*address)[size] = 0;
}
return event;
}
int main (void)
{
void *ctx = zmq_ctx_new ();
assert (ctx);
// We'll monitor these two sockets
void *client = zmq_socket (ctx, ZMQ_REQ);
assert (client);
int reconnectivl = 100;
int zero=0;
zmq_setsockopt(client, ZMQ_RECONNECT_IVL, &reconnectivl, sizeof(int) );
zmq_setsockopt(client, ZMQ_LINGER, &reconnectivl, sizeof(int) );
// Socket monitoring only works over inproc://
int rc = zmq_socket_monitor (client, "tcp://127.0.0.1:10099", ZMQ_EVENT_ALL);
assert (rc == -1);
assert (zmq_errno () == EPROTONOSUPPORT);
// Monitor all events on client and server sockets
rc = zmq_socket_monitor (client, "inproc://monitor-client", ZMQ_EVENT_ALL);
assert (rc == 0);
// Create two sockets for collecting monitor events
void *client_mon = zmq_socket (ctx, ZMQ_PAIR);
zmq_setsockopt(client_mon, ZMQ_LINGER, &zero, sizeof(int) );
assert (client_mon);
// Connect these to the inproc endpoints so they'll get events
rc = zmq_connect (client_mon, "inproc://monitor-client");
assert (rc == 0);
// Now do a basic ping test
rc = zmq_connect (client, "tcp://127.0.0.1:10099");
assert (rc == 0);
{
zmq_msg_t msg;
zmq_msg_init_size(&msg, 100);
zmq_msg_send( &msg, client, ZMQ_SNDMORE);
}
{
zmq_msg_t msg;
zmq_msg_init_size(&msg, 100);
zmq_msg_send( &msg, client, 0);
}
zmq_pollitem_t p[] = { {client, -1, ZMQ_POLLIN | ZMQ_POLLOUT | ZMQ_POLLERR, 0} };
zmq_poll(p, 1, 500);
// Close client and server
zmq_close(client);
// Now collect and check events from both sockets
int event = 0;
do
{
event = get_monitor_event (client_mon, NULL, NULL);
printf("event: %x\n", event);
}
while (event != ZMQ_EVENT_MONITOR_STOPPED);
// Close down the sockets
zmq_close(client_mon);
zmq_ctx_term (ctx);
return 0 ; }
Best wishes,
Jens
--
Jens Auer | CGI | Software-Engineer
CGI (Germany) GmbH & Co. KG
Rheinstraße 95 | 64295 Darmstadt | Germany
T: +49 6151 36860 154
jens.auer at cgi.com<mailto:jens.auer at cgi.com>
Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie unter de.cgi.com/pflichtangaben<http://de.cgi.com/pflichtangaben>.
CONFIDENTIALITY NOTICE: Proprietary/Confidential information belonging to CGI Group Inc. and its affiliates may be contained in this message. If you are not a recipient indicated or intended in this message (or responsible for delivery of this message to such person), or you think for any reason that this message may have been addressed to you in error, you may not use or copy or deliver this message to anyone else. In such case, you should destroy this message and are asked to notify the sender by reply e-mail.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20160913/05496e43/attachment.htm>
More information about the zeromq-dev
mailing list