nanomsg
Home Download Documentation Development Community Support
Getting Started with 'nanomsg'
This document is derived from an original post by Tim Dysinger. That post is no longer available, but we have modified and restructured it, as well as making enhancments and corrections. Tim’s original code is on github, but we recommend using the examples here as they have a number of corrections.
If you want to use the experimental nng library instead, see the document Getting Started with 'nng'.

Bus (Routing)

A Simple Bus

The bus protocol is useful for routing applications, or for building fully interconnected mesh networks. In this pattern, messages are sent to every directly connected peer.

bus.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <nanomsg/nn.h>
#include <nanomsg/bus.h>

void
fatal(const char *func)
{
        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
        exit(1);
}

int
node(const int argc, const char **argv)
{
        int sock;

        if ((sock = nn_socket (AF_SP, NN_BUS)) < 0) {
                fatal("nn_socket");
        }
          if (nn_bind(sock, argv[2]) < 0) {
                fatal("nn_bind");
        }

        sleep(1); // wait for peers to bind
        if (argc >= 3) {
                for (int x = 3; x < argc; x++) {
                        if (nn_connect(sock, argv[x]) < 0) {
                                fatal("nn_connect");
                        }
                }
        }
        sleep(1); // wait for connections
        int to = 100;
        if (nn_setsockopt(sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to,
            sizeof (to)) < 0) {
                fatal("nn_setsockopt");
        }

        // SEND
        int sz_n = strlen(argv[1]) + 1; // '\0' too
        printf("%s: SENDING '%s' ONTO BUS\n", argv[1], argv[1]);
        if (nn_send(sock, argv[1], sz_n, 0) < 0) {
                fatal("nn_send");
        }

        // RECV
        for (;;) {
                char *buf = NULL;
                int recv = nn_recv(sock, &buf, NN_MSG, 0);
                if (recv >= 0) {
                        printf("%s: RECEIVED '%s' FROM BUS\n", argv[1], buf); (1)
                        nn_freemsg(buf);
                }
        }
        return (nn_shutdown(sock, 0));
}

int
main(int argc, const char **argv)
{
        if (argc >= 3) {
                return (node(argc, argv));
        }
        fprintf(stderr, "Usage: bus <NODE_NAME> <URL> <URL> ...\n");
        return 1;
}
1 Blithely assumes message is ASCIIZ string. Real code should check it.
Compilation
gcc bus.c -lnanomsg -o bus
Execution
./bus node0 ipc:///tmp/node0.ipc ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc & node0=$!
./bus node1 ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node1=$!
./bus node2 ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node2=$!
./bus node3 ipc:///tmp/node3.ipc ipc:///tmp/node0.ipc & node3=$!
sleep 5
kill $node0 $node1 $node2 $node3
Output
node0: SENDING 'node0' ONTO BUS
node1: SENDING 'node1' ONTO BUS
node2: SENDING 'node2' ONTO BUS
node3: SENDING 'node3' ONTO BUS
node0: RECEIVED 'node1' FROM BUS
node0: RECEIVED 'node2' FROM BUS
node0: RECEIVED 'node3' FROM BUS
node1: RECEIVED 'node0' FROM BUS
node1: RECEIVED 'node2' FROM BUS
node1: RECEIVED 'node3' FROM BUS
node2: RECEIVED 'node0' FROM BUS
node2: RECEIVED 'node1' FROM BUS
node2: RECEIVED 'node3' FROM BUS
node3: RECEIVED 'node0' FROM BUS
node3: RECEIVED 'node1' FROM BUS
node3: RECEIVED 'node2' FROM BUS
"nanomsg" is a trademark of Garrett D'Amore.