We always define messages using zmq_msg
. When we want to send multi-part messages, again, we need to use zmq_msg
. For example, if the data package is divided into 10 parts, you need to create 10 zmq_msg
sockets. The client either receives all the message parts or nothing at all. In order to send multi-part messages, the ZMQ_SNDMORE
flag must be set during the zmq_send
call.
int zmq_send(void* socket, void* buf, size_t len, int flags);
The following is the request-reply example that we used in Chapter 1, Getting Started, but this time we will send the message in multiple parts. First, let's have a look at the server code:
/* Request - Reply Send "world" in multiple-parts. server.c */ #include <string.h> #include <stdio.h> #include <unistd.h> #include "zmq.h" int main (int argc, char const *argv[]) { void* context = zmq_ctx_new(); void* respond = zmq_socket(context, ZMQ_REP); zmq_bind(respond, "tcp://*:4040"); printf("Starting... "); for(;;) { zmq_msg_t request; zmq_msg_init(&request); zmq_msg_recv(&request, respond, 0); printf("Received: hello "); zmq_msg_close(&request); sleep(1); zmq_msg_t msg1, msg2, msg3, msg4, msg5; zmq_msg_init_size(&msg1, 2); zmq_msg_init_size(&msg2, 2); zmq_msg_init_size(&msg3, 2); zmq_msg_init_size(&msg4, 2); zmq_msg_init_size(&msg5, 2); memcpy(zmq_msg_data(&msg1), "w", 2); zmq_msg_send(&msg1, respond, ZMQ_SNDMORE); memcpy(zmq_msg_data(&msg2), "o", 2); zmq_msg_send(&msg2, respond, ZMQ_SNDMORE); memcpy(zmq_msg_data(&msg3), "r", 2); zmq_msg_send(&msg3, respond, ZMQ_SNDMORE); memcpy(zmq_msg_data(&msg4), "l", 2); zmq_msg_send(&msg4, respond, ZMQ_SNDMORE); memcpy(zmq_msg_data(&msg5), "d", 2); zmq_msg_send(&msg5, respond, 0); zmq_msg_close(&msg1); zmq_msg_close(&msg2); zmq_msg_close(&msg3); zmq_msg_close(&msg4); zmq_msg_close(&msg5); } zmq_close(respond); zmq_ctx_destroy(context); return 0; }
And the following is the client code:
/* Request - Reply Receive "world" in multi-parts. client.c */ #include <string.h> #include <stdio.h> #include <stdint.h> #include <unistd.h> #include "zmq.h" int main (int argc, char const *argv[]) { void* context = zmq_ctx_new(); printf("Client Starting.... "); void* request = zmq_socket(context, ZMQ_REQ); zmq_connect(request, "tcp://localhost:4040"); for(;;) { zmq_msg_t reply; zmq_msg_init(&reply); zmq_msg_recv(&reply, request, 0); printf("Received: %s ", (char *) zmq_msg_data(&reply)); zmq_msg_close(&reply); uint64_t more_part; size_t more_size = sizeof(more_part); zmq_getsockopt(request, ZMQ_RCVMORE, &more_part, &more_size); if (!more_part) break; } zmq_close(request); zmq_ctx_destroy(context); return 0; }
We should note that the last part of the message flag that you send should always be set to 0
. If you set it to ZMQ_SNDMORE
, then the client will not receive any messages.
zmq_msg_t msg1, msg2, msg3, msg4, msg5; zmq_msg_init_size(&msg1, 2); zmq_msg_init_size(&msg2, 2); zmq_msg_init_size(&msg3, 2); zmq_msg_init_size(&msg4, 2); zmq_msg_init_size(&msg5, 2); zmq_msg_send(&msg1, respond, ZMQ_SNDMORE); zmq_msg_send(&msg2, respond, ZMQ_SNDMORE); zmq_msg_send(&msg3, respond, ZMQ_SNDMORE); zmq_msg_send(&msg4, respond, ZMQ_SNDMORE); zmq_msg_send(&msg5, respond, ZMQ_SNDMORE);
The previous code snippet will not work. You could change the relevant parts of server code with it and experience it yourself.
3.19.56.45