[zeromq-dev] How to send/receive a custom C++ object via zeromq.
Riskybiz
riskybizLive at live.com
Sun Sep 29 00:05:28 CEST 2013
I've managed to fix the problem and now am able to use boost::serialization
to pass serialized data via zeromq. I've posted the test program code below
in case it might be of use to someone else trying to do the same in
future..There is a class declaration, a server program and a client program.
The client makes a serialised request and the server sends a serialized
message in reply.
Thanks for help and guidance in getting this to work.
Riskybiz.
//Server
//Intended to send a serialized object instance to a client
#include <zmq.hpp>
#include <string>
#include <sstream>
#include <vector>
#include <boost\archive\text_iarchive.hpp>
#include <boost\archive\text_oarchive.hpp>
#include "TestClass.h"
int main () {
//Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:4444");
//Create a vector with some object instances
std::vector<TestClass> testVec;
for(unsigned int i = 0; i < 10; ++i)
{
std::string idStr = static_cast<std::ostringstream*>( &(std::ostringstream()
<< std::fixed << std::setprecision(0) << i))->str();
TestClass obj(i, "Test Message: " + idStr);
testVec.push_back(obj);
}
while (true)
{
std::cout << "Server ready & waiting...." << std::endl;
zmq::message_t request;
//Wait for next request from client
socket.recv(&request);
//Deserialize client request
int index;
//Cast the request data to a string
std::string reqStr( static_cast<char*>(request.data()), request.size());
//Initialise istringstream with received serialized string data
std::istringstream ibuffer(reqStr);
//Initialise the archive
boost::archive::text_iarchive iarchive(ibuffer);
//Deserialize the archive into the variable
iarchive & index;
std::cout << "Client Requested Index: " << index << std::endl;
//Prepare the reply
std::ostringstream obuffer;
//Initialise the archive
boost::archive::text_oarchive oarchive(obuffer);
//Serialise object at requested vector index
oarchive & testVec.at(index);
//Get the serialization data (a string) from the buffer
std::string outStr(obuffer.str());
//Send data to client
zmq::message_t reply(outStr.size());
memcpy((void *) reply.data(), outStr.data(), outStr.size());
socket.send(reply);
std::cout << "Server Replied: " << outStr << std::endl;
}
return 0;
}
//Client
//Intended to send a request to the server and receive, then deserialize an
object
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <sstream>
#include <boost\archive\text_iarchive.hpp>
#include <boost\archive\text_oarchive.hpp>
#include "TestClass.h"
int main ()
{
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REQ);
std::cout << "Connecting to server...." << std::endl;
socket.connect ("tcp://localhost:4444");
// Do 10 requests, waiting each time for a response
for (int request_nbr = 0; request_nbr != 10; request_nbr++) {
std::ostringstream obuffer;
boost::archive::text_oarchive oarchive(obuffer);
oarchive & request_nbr;//serialize the request
std::string reqStr(obuffer.str());//Get the serialization data (a string)
from the buffer
zmq::message_t request(reqStr.size());
memcpy ((void *) request.data(), reqStr.data(), reqStr.size());
socket.send (request);
std::cout << "Sent Request " << request_nbr << "...." << std::endl;
//Get the reply.
zmq::message_t reply;
socket.recv (&reply);
//std::cout << "Received the reply...." << std::endl;
TestClass obj1;
//std::cout << "Defined TestClass Object...." << std::endl;
std::string repStr( static_cast<char*>(reply.data()), reply.size() );//cast
received message data to a string
//std::cout << "Received Message: " << repStr << std::endl;
std::istringstream ibuffer(repStr);//initialise with received serialized
string data
//std::cout << "Initialised buffer...." << std::endl;
boost::archive::text_iarchive iarchive(ibuffer);
//std::cout << "Prepared archive...." << std::endl;
iarchive & obj1;//deserialise the archive into TestClass instance
//std::cout << "Deserialized...." << std::endl;
//Check that data members of the deserialised object may be accessed
std::cout << "Received: " << request_nbr << " ID: " << obj1.ID << " Message:
" << obj1.text << std::endl;
}
return 0;
}
#ifndef TEST_CLASS_H
#define TEST_CLASS_H
//#include <string>
//#include <boost\archive\text_oarchive.hpp>
//#include <boost\archive\text_iarchive.hpp>
class TestClass
{
public:
TestClass():ID(0), text("blank")//default constructor
{
}
TestClass(const unsigned int id, const std::string txt):ID(id),
text(txt)//constructor
{
}
TestClass::TestClass(const TestClass& orig):ID(orig.ID),
text(orig.text)//copy constructor
{
}
~TestClass()//destructor
{
}
const unsigned int ID;
const std::string text;
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& archive, const unsigned version)
{
archive & const_cast<unsigned int&>(ID) &
const_cast<std::string&>(text);
}
};//class
#endif
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20130928/0837347b/attachment.htm>
More information about the zeromq-dev
mailing list