Alex
Alex

Reputation: 2531

ZeroMQ C# client doesnt receive messages from C++ server

I've tried to program sending messages from one server to multiple clients. I have to use C# on client side, C++ on server side. I took example from http://zguide.zeromq.org/page:all#toc8 for server:

#define within(num) (int) ((float) num * rand () / (RAND_MAX + 1.0))

int main () {

//  Prepare our context and publisher
zmq::context_t context (1);
zmq::socket_t publisher (context, ZMQ_PUB);
publisher.bind("tcp://*:5556");
//publisher.bind("ipc://weather.ipc");

//  Initialize random number generator
srand ((unsigned) time (NULL));
while (1) {

    int zipcode, temperature, relhumidity;

    //  Get values that will fool the boss
    zipcode     = within (100000);
    temperature = within (215) - 80;
    relhumidity = within (50) + 10;

    //  Send message to all subscribers
    zmq::message_t message(20);
    _snprintf ((char *) message.data(), 20 ,
        "%05d %d %d", zipcode, temperature, relhumidity);
    publisher.send(message);

}
return 0;
}

And for client:

namespace ZMQGuide
{
internal class Program
{
    public static void Main(string[] args) {
        Console.WriteLine("Collecting updates from weather server…");

        // default zipcode is 10001
        string zipcode = "10001 "; // the reason for having a space after 10001 is in case of the message would start with 100012 which we are not interested in

        if (args.Length > 0)
            zipcode = args[1] + " ";

        using (var context = new Context(1))
        {
            using (Socket subscriber = context.Socket(SocketType.SUB))
            {
                subscriber.Subscribe(zipcode, Encoding.Unicode);
                subscriber.Connect("tcp://localhost:5556");

                const int updatesToCollect = 100;
                int totalTemperature = 0;

                for (int updateNumber = 0; updateNumber < updatesToCollect; updateNumber++)
                {
                    string update = subscriber.Recv(Encoding.Unicode);
                    totalTemperature += Convert.ToInt32(update.Split()[1]);
                }

                Console.WriteLine("Average temperature for zipcode {0} was {1}F", zipcode, totalTemperature / updatesToCollect);
            }
        }
    }
}
}

They don't communicate with each other. On the client side (C++) I commented line with ipc interaction because on Windows client with ipc is failed. C# - C#, C++ - C++ interactions works correctly in this case. I use clrzmq 2.2.5.

I would appreciate any help.

Upvotes: 4

Views: 1846

Answers (1)

Alex
Alex

Reputation: 2531

C# client is using Encoding.Unicode, which is a 2-byte unicode representation (UTF-16). C++ server is using ASCII.

ZMQ subscription matching works on the byte level and does not convert between character encodings, so this is where my issue is. Switching to Encoding.ASCII or Encoding.UTF8 in C# client solves this issue.

Upvotes: 7

Related Questions