1


I am trying to get the Radio/Dish pattern in ZeroMQ (libzmq with plain C) to work. Ultimately I want to use UDP multicasting but I cannot even get TCP unicast to work. The following minimal example does not work for me. I tried the Pub/Sub example from the official guide and I can confirm that generally ZeroMQ over TCP works on my machine but not Radio/Dish. What am I missing?

Radio:

#define ZMQ_BUILD_DRAFT_API

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

int main(int argc, char *argv[]) {
    if (argc < 3) {
        printf("Please provide topic and message.");
        return EXIT_FAILURE;
    }

    void *context = zmq_ctx_new();
    void *radio = zmq_socket(context, ZMQ_RADIO);
    if (zmq_connect(radio, "tcp://127.0.0.1:5556") != 0) {
        printf("Failed to connect sending socket.");
        return EXIT_FAILURE;
    }

    zmq_msg_t msg;
    if (zmq_msg_init_data(&msg, argv[2], strlen(argv[2]), NULL, NULL) != 0) {
        printf("Failed to init message for topic %s.", argv[1]);
        return EXIT_FAILURE;
    }
    if (zmq_msg_set_group(&msg, argv[1]) != 0) {
        printf("Failed to set topic %s.", argv[1]);
        return EXIT_FAILURE;
    }
    if (zmq_msg_send(&msg, radio, 0) == -1) {
        zmq_msg_close(&msg);
        printf("Failed to send message \"%s\" on topic %s.", argv[2], argv[1]);
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Dish:

#define ZMQ_BUILD_DRAFT_API

#include <stdlib.h>
#include <stdio.h>
#include <zmq.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("Please provide a topic.");
        return EXIT_FAILURE;
    }

    void *context = zmq_ctx_new();
    void *dish = zmq_socket(context, ZMQ_DISH);
    if (zmq_bind(dish, "tcp://*:5556") != 0) {
        printf("Failed to bind listen socket.");
        return EXIT_FAILURE;
    }

    if (zmq_join(dish, argv[1]) != 0) {
        printf("Could not subscribe to %s.", argv[1]);
        return EXIT_FAILURE;
    }

    int bytesReceived;
    zmq_msg_t receiveMessage;

    zmq_msg_init(&receiveMessage);
    bytesReceived = zmq_msg_recv(&receiveMessage, dish, 0);
    if (bytesReceived == -1) {
        printf("Failed to receive message.");
    } else {
        printf("topic: %s, data: %s, size: %d", zmq_msg_group(&receiveMessage), (char *)zmq_msg_data(&receiveMessage), bytesReceived);
    }

    zmq_msg_close(&receiveMessage);

    return EXIT_SUCCESS;
}

Run:

dish.exe TV
radio.exe TV test_msg

The dish seems to listen and the radio does its thing without errors but the dish does never receive anything. Both executables are run on the same machine. Thank you in advance.

user3563584
  • 403
  • 1
  • 4
  • 6
  • Would you mind to rerun the same test inside a linux ecosystem or using the **`ipc://aNamedIpcCHANNEL`** channel, so as to isolate the root-cause ( translation of symbolic interface addresses and matching the wildcard expansion mappings )? – user3666197 Mar 10 '20 at 16:12
  • @user3666197 Thanks for the reply. Sadly I have no access to a linux machine atm. But here is the PUB/SUB code I tested https://pastebin.com/8efWAYT9 . This works fine on my machine and it also uses a wildcard for the publisher. Btw. I am using libzmq version 4.3.2. – user3563584 Mar 11 '20 at 09:49

1 Answers1

0

So i figured it out myself. The problem is in the Radio/Publisher. The Program must not end right after the zmq_msg_send otherwise the message will not be send. I added a proper zmq_ctx_destroy(context) before returning and that fixed the issue.
According to the documentation zmq_ctx_destroy(context) waits for pending messages to be sent before shutting down. That seems to have been the issue.

user3563584
  • 403
  • 1
  • 4
  • 6