[zeromq-dev] Sending via ROUTER socket to ROUTER socket fails initially with "No route to host"

Anoop Karollil anoop.karollil at gmail.com
Tue Mar 26 00:53:22 CET 2013


Hello,

I am using ZeroMQ 3.2.2 and PyZMQ 13.0.0.

When I try sending messages via a ROUTER socket to a ROUTER socket (both 
having their identities set), with ZMQ_ROUTER_MANDATORY set, the initial 
send of the destination sock identity (sent before actual message for 
routing) fails once, but succeeds after.

Please see attached C or Python file which reproduces the behavior. It 
seems to happen only if the SNDMORE option is set - which if my 
understanding is correct is what should be done while sending the 
destination socket identity, before the actual message is sent with the 
SNDMORE flag unset.

Is this intended behavior or am I doing something wrong?

The C program gives the following output:


Sending address...
Error: No route to host
Sending address...
Success!
Sending Hello...
Success!



Thanks,
Anoop
-------------- next part --------------
#include <zmq.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define URI "tcp://127.0.0.1:20000"

void main()
{
    void *ctx = zmq_ctx_new();
    assert(ctx);

    void *broker = zmq_socket(ctx, ZMQ_ROUTER);
    assert(broker);

    char *broker_id = "BROKER";
    int rc = zmq_setsockopt(broker, ZMQ_IDENTITY, broker_id, strlen(broker_id));
    assert(!rc);

    int option = 1;
    rc = zmq_setsockopt(broker, ZMQ_ROUTER_MANDATORY, &option, sizeof(option));
    assert(!rc);

    rc = zmq_bind(broker, URI);
    assert(!rc);

    void *client = zmq_socket(ctx, ZMQ_ROUTER);
    assert(client);

    char *client_id = "CLIENT";
    rc = zmq_setsockopt(client, ZMQ_IDENTITY, client_id, strlen(client_id));
    assert(!rc);

    option = 1;
    rc = zmq_setsockopt(client, ZMQ_ROUTER_MANDATORY, &option, sizeof(option));
    assert(!rc);
    
    rc = zmq_connect(client, URI);

    char *msg = "Hello";
    int sent_addr = 0;
    while(1) {

        if (!sent_addr) {
            printf("Sending address...\n");
            rc = zmq_send(client, broker_id, strlen(broker_id), ZMQ_SNDMORE);
        } else {
            printf("Sending %s...\n", msg);
            rc = zmq_send(client, msg, strlen(msg), 0);
        }

        if (rc > 0) {
            printf("Success!\n");
            if (sent_addr)
                break;
            else
                sent_addr = 1;
        } else {
            printf("Error: %s\n", zmq_strerror(errno)); 
            sleep(1);
        }

    }
}

-------------- next part --------------
import zmq
import time
import sys

broker_uri = "tcp://127.0.0.1:20000"

context = zmq.Context()

broker = context.socket(zmq.ROUTER)
broker.setsockopt(zmq.IDENTITY, "BROKER")
broker.setsockopt(zmq.ROUTER_BEHAVIOR, 1)
broker.bind(broker_uri)

client = context.socket(zmq.ROUTER)
client.setsockopt(zmq.IDENTITY, "CLIENT")
client.setsockopt(zmq.ROUTER_BEHAVIOR, 1)
client.connect(broker_uri)

while True:
    try:
        client.send_multipart(["BROKER", "Hello"])
    except zmq.error.ZMQError, e:
        print("Error: %s" % e)
    else:
        print("Success!")
        break
    time.sleep(1)



More information about the zeromq-dev mailing list