This is the next problem I discovered earlier in another thread in Boost: De-serializing a custom C ++ object passed through the ZeroMQ pull socket . The problem in this thread was resolved based on the answer provided. Now I have another runtime problem. Please see the description below. I am completely unfamiliar with the C ++ area, so I appreciate if you tell me any need to improve any part of the code provided in addition to what I described in the status of the problem.
Description:
I have a C ++ class called GenericMessage that simply contains an identifier and data as its members (see code snippet 2 below - GenericMessage.hxx). My intention is to serialize an instance of this class and send it through the ZeroMQ socket, which implements the push pattern.
The serialization and sending task was implemented in the ZMQHandler class (see the sendToBE function), which is placed in the name of the ZMQHandler.hxx header file, shown in code snippet 3 below. This class is created by TestFE.cxx , shown in the 4th code fragment below.
Retrieving and de-serializing an instance of GenericMessage is implemented in TestBE.cxx , available in the fifth code snippet below. My intention is to get an instance of GenericMessage through a ZMQ socket (i.e. a Pull socket), de-serialize it, and then print its elements to standard output.
I checked that the seriazalition and the GenericMessage object that is being passed through the ZeroMQ socket work fine. It seems that deserialization also works because I am not getting any exception or segmentation error as a thing.
Problem:
TestBE.cxx(. 5), GenericMessage ZeroMQ, , , , . , char, , - . . Al, , , char. . , .
:
i) ? , ? , char?
ii) GenericMessage , std::string. , , . , , boost:: archive:: text_iarchive boost:: archive:: text_oarchive. ? , - / , , , ? .
SNIPPET 1:
*******************
The EXPECTED OUTPUT
*******************
Connecting to FE...
CHAR [22 serialization::archive 9 0 1 0
0 1 12 Hello there!]
ID: 1
Data: Hello there!
CHAR [22 serialization::archive 9 0 1 0
0 2 12 Hello there!]
ID: 2
Data: Hello there!
CHAR [22 serialization::archive 9 0 1 0
0 3 12 Hello there!]
ID: 3
Data: Hello there!
......
*************************
PRINTED OUTPUT IN REALITY
*************************
Connecting to FE...
CHAR [22 serialization::archive 9 0 1 0
0 1 12 Hello there!]
ID: 1
Data: Hello there!
//continues in increasing order same as above until the 18th message in the following
CHAR [22 serialization::archive 9 0 1 0
0 18 12 Hello there!]
ID: 0
Data:
//!!!!AFTER the 18th message I got question marks in the printed char stream!!!!!
CHAR [22 serialization::archive 9 0 1 0
0 19 12 Hello there! ]
ID: 0
Data:
CHAR [22 serialization::archive 9 0 1 0
0 20 12 Hello there! ]
ID: 0
Data:
CODE SNIPPET 2 (GenericMessage.hxx)
#include <iostream>
#include <string>
#include <sstream>
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
template <class T>
class GenericMessage {
public:
GenericMessage():
beId(-1)
{}
GenericMessage(int id, T msg):
beId(id),
data(msg)
{}
~GenericMessage(){}
T getData()
{
return data;
}
std::string toString()
{
std::ostringstream ss;
ss << getBeId();
std::string ret = ss.str();
return ("ID: " + ret + " DATA: " + getData());
}
void setBeId(int id)
{
beId = id;
}
int getBeId()
{
return beId;
}
private:
friend class boost::serialization::access;
int beId;
T data;
template <class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & beId;
ar & data;
}
};
CODE SNIPPET 3 (ZmqHandler.hxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <unistd.h>
#include <cassert>
template <class A>
class ZmqHandler {
public:
ZmqHandler():
mContext(1),
mOutbHandlerSocket(mContext, ZMQ_PUSH)
{
mOutbHandlerSocket.bind ("tcp://*:5555");
}
~ZmqHandler() {}
void sendToBE(GenericMessage<A> *theMsg)
{
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
try
{
archive << theMsg;
} catch (boost::archive::archive_exception& ex) {
std::cout << "Archive Exception during deserializing:" << std::endl;
std::cout << ex.what() << std::endl;
} catch (int e) {
std::cout << "EXCEPTION " << e << std::endl;
}
std::string outbound_data_ = archive_stream.str();
int len = outbound_data_.length();
zmq::message_t msgToSend(len);
memcpy( msgToSend.data(), outbound_data_.data(), len );
mOutbHandlerSocket.send(msgToSend);
std::cout << "SENT request: [" << theMsg->toString() << "]" << std::endl;
std::cout << "LENGTH [" << len << "]" << std::endl;
}
private:
zmq::context_t mContext;
zmq::socket_t mOutbHandlerSocket;
};
CODE SNIPPET 4 (TestFE.cxx)
#include "ZmqHandler.hxx"
int main ()
{
ZmqHandler<std::string> zmqHandler;
int counter = 1;
while(1)
{
std::string data = "Hello there!";
GenericMessage<std::string> msg(counter, data);
zmqHandler.sendToBE(&msg);
counter++;
sleep(1);
}
return 0;
}
CODE SNIPPET 5 (TestBE.cxx)
#include "zmq.hpp"
#include "GenericMessage.hxx"
#include <fstream>
int main ()
{
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_PULL);
std::cout << "Connecting to FE..." << std::endl;
socket.connect ("tcp://localhost:5555");
while(1){
zmq::message_t reply;
socket.recv (&reply);
const char *buf = static_cast<const char*>(reply.data());
std::cout << "CHAR [" << buf << "]" << std::endl;
std::string input_data_( buf, reply.size() );
std::istringstream archive_stream(input_data_);
boost::archive::text_iarchive archive(archive_stream);
GenericMessage<std::string> theMsg;
try
{
archive >> theMsg;
} catch (boost::archive::archive_exception& ex) {
std::cout << "Archive Exception during deserializing:" << std::endl;
std::cout << ex.what() << std::endl;
} catch (int e) {
std::cout << "EXCEPTION " << e << std::endl;
}
std::cout << "ID: " << theMsg.getBeId() << std::endl;
std::cout << "Data: " << theMsg.getData() << std::endl;
}
return 0;
}