Working with multi-part messages

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.56.45