zeromq: an easy-to use IPC mechanism

Zeromq is a library that makes IPC as simple as reading and writing messages. No multithreading is required, as zermoq handles all the fuss of queuing and dispatching messages.

IPC (Inter Process Communication) is something I have been interested in for awhile, but found it very difficult to write usable code. One weird idea I had was to make an ncurses server. The idea is that you would open a terminal, start and start this ncurses server. You could then send commands to that server, and it would move the cursor about and display text that it was told to. Anybody would be able to send it a message, so it wouldn’t be intended to be tied to one process.

It turns out that zeromq is an ideal candidate for this, and I found out about it when I started digging into IPython, and found out that it uses it as a communication transport mechanism. Zeromq is easy to use, as I’ll illustrate in the example below.

I’m going to build a little server and client. The purpose of the zero is to return a number. Every time you call the server, it will give you back the next number in the sequence.

Here’s the server:

#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>

int count = 0;

int main (void)
{
  // Socket to talk to clients
  void *context = zmq_ctx_new ();
  void *responder = zmq_socket (context, ZMQ_REP);
  int rc = zmq_bind (responder, "tcp://*:5555");
  assert (rc == 0);

  while (1) {
    char buffer [20];
    zmq_recv (responder, buffer, 20, 0);
    printf ("Received Hello\n");
    sleep (1); // Do some 'work'
    sprintf(buffer, "Answer: %d\n", count);
    zmq_send (responder, buffer, 20, 0);
    count++;
  }
  return 0;
}

You compile it using a command like:
gcc -o server server.c -lzmq

You will need to install the zeromq dev library, of course. It is likely to be available on most distributions. Ubuntu users are, of course, amply covered. ‘count’ holds the sequential value, which is incremented after sending each response. Notice how conceptually simple the code is. It’s really no more complicated than reading or writing to a file.

Now let’s write the client:

#include <zmq.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>


int main (void)
{
  printf ("Connecting to hello world server…\n");
  void *context = zmq_ctx_new ();
  void *requester = zmq_socket (context, ZMQ_REQ);
  zmq_connect (requester, "tcp://localhost:5555");

  printf ("Sending Hello \n");
  zmq_send (requester, "Hello", 5, 0);
  zmq_recv (requester, buffer, 20, 0);
  printf ("Received World %s\n", buffer);

  zmq_close (requester);
  zmq_ctx_destroy (context);
  return 0;
}

Again, this is very straightforward. You can see that we’re using port 5555 as communication port. Compile it: gcc -o client client.c -lzmq

Start the server: ./server &

Send a message to this server by typing: ./client
You get back the response:
Connecting to hello world server…
Sending Hello
Received Hello
Received World Answer: 0

Run it again: ./client
The response this time is:
Connecting to hello world server…
Sending Hello
Received Hello
Received World Answer: 1

And so on, and so forth.

Very neat. Zeromq has bindings for Python, as you’d expect, but there are bindings for many other languages, including Haskell, Lua, Java, Perl, and so on.

Advertisements

About mcturra2000

Computer programmer living in Scotland.
This entry was posted in Computers and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s