0
votes

I am trying to get a Scala program to communicate with a c++ program via zeromq by using the request-reply pattern. The scala program should send a request to the C++ program which replies.

However I see the error

org.zeromq.ZMQException: Operation cannot be accomplished in current state

But all I can find in the docu is that one has to read responses before sending a second request. In my case I am issuing a request, followed by a reading of the response (this is where the exception is thrown).

Code of the server:

#include "zmq.hpp"
#include <string>
#include <iostream>
#include <thread>

int main()
{
    zmq::context_t context(1);
    zmq::socket_t socket(context, ZMQ_REP);
    socket.bind("tcp://*:5555");


    while (1) {
        zmq::message_t request;
        socket.recv(&request);
        std::string requ = std::string(static_cast<char*>(request.data()), request.size());
        std::cout << requ << std::endl;

        //  Write response
        zmq::message_t req(2);
        memcpy((void *)req.data(), "ok", 5);
        socket.send(req);
    }
}

Code of the client:

import org.zeromq.ZMQ
import org.zeromq.ZMQ.{Context, Socket}

object Adapter {
  def main( args: Array[String] ) = {
    val context = ZMQ.context(1)
    val socket = context.socket(ZMQ.REQ)
    println { "Connecting to backend" }
    socket.connect("tcp://127.0.0.1:5555")
    val request = "1 1 1 1".getBytes()
    request(request.length - 1) = 0.toByte
    println { "Sending Request" }
    if (!socket.send(request, 0))
      println{ "could not send"}
    println { "Receiving Response" }
    val reply = socket.recv(0)
    println { "Received reply: " + new String(reply, 0, reply.length - 1) }
  }
}

The complete output of sbt:

OpenJDK 64-Bit Server VM warning: You have loaded library /tmp/jna7980154308052950568.tmp which might have disabled stack guard. The VM will try to fix the stack guard now.
It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.
Connecting to backend
Sending Request
Receiving Response
[error] (run-main-0) org.zeromq.ZMQException: Operation cannot be accomplished in current state
org.zeromq.ZMQException: Operation cannot be accomplished in current state
        at org.zeromq.ZMQ$Socket.raiseZMQException(ZMQ.java:448)
        at org.zeromq.ZMQ$Socket.recv(ZMQ.java:368)
        at ZeroMQActor$.main(ZeroMQExample.scala:56)
        at ZeroMQActor.main(ZeroMQExample.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
[error] Total time: 5 s, completed Jun 16, 2015 4:42:42 PM

Sbt pulls Scala 2.9.1 and akka-zeromq 2.0. I have installed zeromq 3.5 from source but I see the same behavior when I install the ubuntu package libzqm3-dev. One possible work-around is using JeroMQ, a pure java-based implementation of zmq, but I would prefer to depend on one zmq library in my whole stack rather than dealing with interop issues.

Thanks in advance.

1
Just for kicks, if you haven't done so already, try running a generic REQ/REP example in pure scala such as this one (look for the scala link to get scala code). If it runs, then switch the Scala server example code with the C++ server example code and try again. If it runs, there's a bug somewhere in your string/message handling. If it doesn't, there's likely a bug in your installation or language bindings.Jason

1 Answers

0
votes

I believe

memcpy((void *)req.data(), "ok", 5);

should be

memcpy((void *)req.data(), "ok", 2);

... which could be enough to break message handling.