如何使用ZMQ发送字符串结构

时间:2014-06-19 13:51:43

标签: c++ string struct zeromq

我想通过比较接收节点B上两者的时间戳来比较群集的两个节点A和B之间的延迟。为此,我使用预先存在的整数结构,但添加了一个字符串保存节点A的时间戳。

结构看起来像这样:

struct Content {
  int id;
  double a;
  std::vector<char> timestamp;
};

要在节点A准备数据,我使用以下内容:

int fEventSize = 100;

Content* payload = new Content[fEventSize];

boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();

std::string str = to_simple_string(mst1);
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');

(&payload[0])->timestamp = writable;

我随后创建了一条ZMQ消息,我记录了该消息的有效负载,并像往常一样将其发送到节点B.要验证时间戳是否在节点A上正确写入,以下工作正常:

cout << &(&payload[0])->timestamp[0]; << endl;

但是在节点B的接收端,虽然我可以正确打印id的值和结构的成员,但是当我尝试打印时间戳的值时,我得到了分段错误:

Content* input = reinterpret_cast<Content*>(msg->GetData());

cout << "x: " << (&input[0])->x << endl;

cout << "timestamp: " << &(&input[0])->timestamp[0] << endl;

为什么?这是使用ZMQ发送结构字符串成员的正确方法吗?

1 个答案:

答案 0 :(得分:0)

要回答我的问题,以下内容适用于我:

结构看起来像这样:

struct Content {
  int id;
  double a;
  char timestamp[30];
};

在节点A上:

//Create a high resolution timestamp in microseconds
boost::posix_time::ptime mst1 = boost::posix_time::microsec_clock::local_time();

//Convert the timestamp into an std::string
std::string str (to_simple_string (mst1));

//Copy the string to the struct member
std::size_t length = str.copy ((&payload[0])->timestamp, strlen(str.c_str()), 0);
(&payload[0])->timestamp[length]='\0';

//Copy the contents of the Content struct to the ZMQ message
memcpy(msg->GetData(), payload, fEventSize * sizeof(Content));

在节点B上:

//Cast the data to an input pointer of type Content
Content* input = reinterpret_cast<Content*>(msg->GetData());

std::cout << (&input[0])->timestamp << std::endl;

但是,实际上有一个更好的解决方案,就是直接通过线路发送时间戳:

结构看起来像这样:

struct Content {
  int id;
  double a;
  boost::posix_time::ptime timestamp;
};

在节点A上:

(&payload[0])->timestamp = boost::posix_time::microsec_clock::local_time();

//Copy the contents of the Content struct to the ZMQ message
memcpy(msg->GetData(), payload, fEventSize * sizeof(Content));

在节点B上:

//Cast the data to an input pointer of type Content
Content* input = reinterpret_cast<Content*>(msg->GetData());

//Convert the timestamp into a string
std::string mystr (to_simple_string ((&input[0])->mytimestamp));
cout << mystr.c_str() << endl;

这样,很多花哨的东西可以在客户端完成,而不必在时间戳和字符串之间不断转换,例如,计算节点A和B之间的发送延迟(假设节点具有同步时钟)。