d3k
d3k

Reputation: 629

EAGAIN received on zeromq REQ/REP without blocking socket

I am getting back to life a three years old project built on zeromq.

The code was working (as far as I know) at the moment when the code was written (on ubuntu 14.04). Now (ubuntu 16.04 and libzmq.so.5) the code compiles but something is wrong with the zeromq communication, and this is getting me crazy.

The zeromq part was written by me, so I know the code quite well, and maybe this is why I cannot see the error.

The server side code is quite complex but I try to stick to the relevant part:

WorkerServer::WorkerServer(){
    address="tcp://*:4321";
    justreceived=-1;
    bind();
}

void WorkerServer::bind(){
    actual_socket=server_socket();
    actual_socket->bind(address.c_str());
    std::cout << "I: server listening on " << address.c_str() << std::endl ;
}

static zmq::socket_t* server_socket(){
    static zmq::context_t context(1);
    return new zmq::socket_t(context, ZMQ_REP);
}

After initialization, the server starts an endless loop that calls these lines of code:

int rc=actual_socket->recv(&message);
if(rc!=0){
    std::cout << "E: socket error number " << errno << " (" << zmq_strerror(errno) << ")" << std::endl;
}else{
    std::cout << "I: received message" << std::endl ;
}

When I compiled it for the first time, I started to receive just EAGAIN errors and nothing was working. So, I wrote two simple clients, the first one in C++ and the second one in Python.

The first one (C++) generates on the client this error:

E: connect failed with error 11 (Resource temporarily unavailable)

and the second one (Python) generates on the server this error:

E: socket error number 11 (Resource temporarily unavailable)

but the client actually receives a reply.

This is the python code:

#!/usr/bin/python

import zmq
import sys

port = "4321"    
context = zmq.Context()
print "Connecting to server..."
socket = context.socket(zmq.REQ)
socket.connect ("tcp://localhost:%s" % port)
if len(sys.argv) > 2:
    socket.connect ("tcp://localhost:%s" % port1)

#  Do 10 requests, waiting each time for a response
for request in range (1,10):
    print "Sending request ", request,"..."
    socket.send ("Hello")
    #  Get the reply.
    message = socket.recv()
    print "Received reply ", request, "[", message, "]"

and this is the c++ code:

#include <string>
#include <vector>
#include <iostream>
#include "msgpack.hpp"
#include "unistd.h"
#include "cxxabi.h"
#include "zmq.hpp"

main(){

    std::string server_name("tcp://localhost:4321");

    static zmq::context_t context(1);
    std::cout << "I: connecting to server " << server_name << " with context " << (void*)(context) << std::endl;
    zmq::socket_t * client = new zmq::socket_t (context, ZMQ_REQ);
    std::cout << "I: created client " << (void*)(client) << " with errno " << errno << std::endl;
    sleep(1);
    client->connect (server_name.c_str());
    if(errno!=0){
        std::cout << "E: connect failed with error " << errno << " (" << zmq_strerror (errno) << ")" << std::endl;
        exit(1);
    }
}

Any idea? I do not understand why this does not work and why there is such a difference between python and c++.

UPDATE:

As pointed by @James Harvey, this code works... :

try{
        std::cout << "Connecting..." << std::endl;
        client->connect (server_name.c_str());

        zmq::message_t request (5);
        memcpy (request.data (), "Hello", 5);
        std::cout << "Sending Hello " << std::endl;
        client->send (request);
}catch(std::exception& e){
        std::cout << "E: connect failed with error " << e.what() << std::endl;    
}

I was thinking that, since the zmqpp is built upon the C bindings, testing for errno or catching the exception was the same. Actually, it is not.

Upvotes: 1

Views: 2506

Answers (1)

jamesdillonharvey
jamesdillonharvey

Reputation: 1042

In your c++ code are you using the cppzmq bindings? If so you should use try/catch on the connect to see if its failing, the errno is only valid if connect fails.

https://github.com/zeromq/cppzmq/blob/master/zmq.hpp#L603

Upvotes: 1

Related Questions