I wanted to flag the following issue:
Platform: win64 / debug, using visual studio 2010 compiler
Language: C++
ZMQ version: 3.1.0
Description:
A router socket and dealer socket, in separate apps, enjoy a good TCP
connection and are sending/receiving messages directly. The messages being sent
from the dealer to the router do not have an empty first frame.
The application using the router socket is killed, then brought back up.
An assertion is generated (in std lib xtree).
When the dealer sends msgs with an empty first-frame this problem does not
occur.
It appears that during a reconnection, the ROUTER socket relies on there being
an empty frame. Further anecdotal evidence of this comes from the fact that
when the dealer socket is configured to send every message with an empty-frame,
recv()s is done on the router socket fail to provide an empty frame for the
first message received after a reconnection with the dealer.
It may be that empty frames are mandated when communicating directly to a
ROUTER socket. If this is the case can this please be documented.
Another interesting quirk:
In this dealer reconnecting with router scenario, the dealer would usually
receive one unexpected message with a single empty frame from the router after
a reconnection.
Example code:
This is experimental code I wrote to try reproducing and debugging the
assertion. By passing in the 'server' command line arg it will run as a server,
with router socket, if 'client' argument then as a client with a dealer
#include <zmq.hpp>
#include <string>
#include <memory>
#include <iostream>
int main(int argc, char ** argv)
{
if (argc >= 2)
{
zmq::context_t context(1);
if (strcmp(argv[1], "server") == 0)
{
zmq::socket_t serverSock(context, ZMQ_XREP);
serverSock.bind("tcp://*:6010");
// record the uuid at first contact (a hack admittedly - hope the
client never restarts)
zmq::message_t message;
serverSock.recv( &message, 0 );
std::string client_uuid ( static_cast<char*>( message.data()),
message.size() );
int msg_count = 0;
while (1)
{
// print out any message we received as a string
zmq::message_t recvdMsg;
serverSock.recv( & recvdMsg, 0 );
std::string msg ( static_cast<char*>(
recvdMsg.data()),recvdMsg.size() );
std::cout << "Recv: " << msg << std::endl;
// for every three frames received, send a reply
msg_count++;
if (msg_count % 3 == 0)
{
// send uuid frame
zmq::message_t msgToSnd(client_uuid.size()) ;
memcpy(msgToSnd.data(),client_uuid.data(),client_uuid.size());
serverSock.send(msgToSnd, ZMQ_SNDMORE);
// send reply body
std::string body("hello");
zmq::message_t msgToSnd2(body.size()) ;
memcpy(msgToSnd2.data(),body.data(),body.size());
serverSock.send(msgToSnd2, 0);
}
}
}
else if (strcmp(argv[1], "client") == 0)
{
zmq::socket_t clientSock(context, ZMQ_XREQ);
clientSock.connect("tcp://localhost:6010");
while (1)
{
Sleep(1000);
/* Uncomment this block to make it is so server can reconnect
without an assert failing
// Send an empty frame
zmq::message_t emptyMsg;
clientSock.send(emptyMsg, ZMQ_SNDMORE);
*/
//Send request body
std::string request("Hello!");
zmq::message_t msgToSnd(request.size()) ;
memcpy(msgToSnd.data(),request.data(),request.size());
clientSock.send(msgToSnd, 0);
//Check if we've received any replies
zmq::message_t recvdMsg;
if (clientSock.recv( & recvdMsg, ZMQ_DONTWAIT ))
{
std::string msg ( static_cast<char*>(
recvdMsg.data()),recvdMsg.size() );
std::cout << "Recv: " << msg << std::endl;
}
}
}
}
}
Kind regards,
Andrew Bott
_______________________________________________
zeromq-dev mailing list
[email protected]
http://lists.zeromq.org/mailman/listinfo/zeromq-dev