问题
There are two endpoints, which are Dealer and Router. The Dealer is connected to the Router by TCP protocol. I set ZMQ_SNDHWM
and ZMQ_RCVHWM
to only one for all of them.
Note that the Dealer always sends message to Router, but the Router does not to do any receiving operation.
When I only start the Dealer, the Dealer only send out one message.That`s expected. But when I start the Router after that, the Dealer can send out about 4 thousands message unexpectedly.
why the ZMQ_RCVHWM
option seems to be invalid?
The code for Dealer:
// create ctx
void* ctx = zmq_ctx_new();
assert(nullptr != ctx);
// create in
void* in = zmq_socket(ctx, ZMQ_DEALER);
assert(in);
int sndhwm = 1;
assert(0 == zmq_setsockopt(in, ZMQ_SNDHWM, &sndhwm, sizeof(sndhwm)));
assert(0 == zmq_setsockopt(in, ZMQ_RCVHWM, &sndhwm, sizeof(sndhwm)));
int rc = zmq_connect(in, "tcp://127.0.0.1:1012");
assert(!rc);
char content[100] = {0};
int size = 0;
int64_t nCount = 0;
while(1)
{
sprintf_s(content, "%d", ++nCount);
size = strlen(content);
rc = zmq_send(in, content, size, 0);
assert(rc = size);
printf("in = %d\n", nCount);
}
The code for Router:
// create ctx
void* ctx = zmq_ctx_new();
void* out = zmq_socket(ctx, ZMQ_ROUTER);
int sndhwm = 1;
assert(0 == zmq_setsockopt(out, ZMQ_SNDHWM, &sndhwm, sizeof(sndhwm)));
assert(0 == zmq_setsockopt(out, ZMQ_RCVHWM, &sndhwm, sizeof(sndhwm)));
int rc = zmq_bind(out, "tcp://127.0.0.1:1012");
assert(!rc);
回答1:
I reply here since I understand this is the newer question, but I was derived from this other question of yours.
The behavior you describe seems to be correct, since (emphasis mine, quoted from here):
"The high water mark is a hard limit on the maximum number of outstanding messages ØMQ shall queue in memory for any single peer that the specified socket is communicating with".
Once you read the message it is no longer queued in memory, hence new messages are accepted. The same applies to sent messages, and this is reflected in the behavior you described (in the first question):
- When the Router is not set up, the Dealer just sends one message and is then obstructed. That is right, because ZMQ_SNDHWM is 1.
Since no peer is yet connected the first message is queued in memory and no new messages are accepted or eligible to be sent.
- But when I setup the Router, the Dealer can continue send about 4K msg and obstructed. Why?
Now the two peers are connected and messages flow freely since no memory queuing is done (you read the socket constantly in your receive loop, posted in your first question which link I've provided above):
The code for Router:
//...
while(true)
{
zmq_msg_init(&msg);
rc = zmq_recvmsg(out, &msg, 0);
assert(rc > 0);
printf("out = %s\n", (char*)zmq_msg_data(&msg));
if(!zmq_msg_more(&msg))
{
break;
}
}
//...
If you stress your system enough to the point that incoming or outgoing messages start queuing up in memory (i.e. exceed socket send capacity -throughput-), you will see the effects of ZMQ_SNDHWM
and ZMQ_RCVHWM
.
来源:https://stackoverflow.com/questions/36512643/how-to-understand-the-zmq-rcvhwm-option-of-zeromq-correctly