c++ - 发送包含其他结构的结构作为 ZeroMQ 消息

标签 c++ arrays struct zeromq

我在发送从指向结构的指针构建的 zmq 消息时遇到问题,该结构包含其他结构。

服务器代码:

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

using namespace zmq;
using namespace std;

struct structB{
    int a;
    string c;
};

struct structC{
    int z;
    struct structB b;
};

int main()
{
    context_t context(1);
    socket_t *socket = new socket_t(context,ZMQ_REP);
    socket->bind("tcp://*:5555");

    message_t *request = new message_t();   
    socket->recv(request);

    struct structB messageB; 
    messageB.a=0;
    messageB.c="aa";

    struct structC *messageC = new struct structC;
    messageC->z = 4;
    messageC->b = messageB;

    char *buffer = (char*)(messageC);
    message_t *reply = new message_t((void*)buffer,
                       +sizeof(struct structB)
                       +sizeof(struct structC)
                       ,0);
    socket->send(*reply);

    return 0;
}

客户端代码:

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

using namespace std;
using namespace zmq;

struct structB{
    int a;
    string c;
};

struct structC{
    int z;
    struct structB b;
};

int main()
{ 
    context_t context(1);
    socket_t *socket = new socket_t(context,ZMQ_REQ);
    socket->connect("tcp://*:5555");

    const char* buffer = "abc";
    message_t *request = new message_t((void*)buffer,sizeof(char*),0);
    socket->send(*request);

    message_t *reply = new message_t;
    socket->recv(reply);

    struct structC *messageC = new struct structC;
    messageC = static_cast<struct structC*>(reply->data());

cout<<messageC->b.a<<endl;//no crash here

    struct structB messageB = messageC->b;//Segmentation fault (core dumped)

    return 0;
}

当我尝试使用 structB 中名为“c”的字符串时,此程序崩溃。无论我尝试打印它,还是像上面的示例一样分配整个 structB,都没有关系。

问题出在哪里?我应该以不同的方式在服务器端创建 message_t *reply 吗?

最佳答案

您不能发送 string通过网络,因为 std::string 是一个容器。您可以使用 flexible array member或大数组或编写一个小类 serializable (需要自己写代码准备buffer)发送数据。

当您执行 struct structB messageB = messageC->b; 时,嵌入在 messageC->b 中的 std::string 成员的指针成员可能在复制构造函数中取消引用或可能导致段错误的 std::string

大字符数组的例子是:

struct structB{
    int a;
    char c[MAX_LENGTH];
};

稍后

struct structB messageB; 
messageB.a=0;
strcpy(messageB.c,"aa"); // #include<cstring> or use std::copy from <algorithm>

struct structC *messageC = new struct structC;
// I guess you want this(not sure) messageC->z = static_cast<int>( sizeof(int) + strlen(messageB) + 1 );
messageC->z = 4;
messageC->b = messageB;

然后

const int length = sizeof(int) /* z */ + sizeof(int) /* a */ + strlen("aa") + 1;
zmq::message_t msg (length);
memcpy (msg.data (), &messageC, length);
socket->send(msg);

这些是服务器端所需的一些更改,您也需要在客户端进行类似的更改。

附带说明一下,您的代码非常困惑,在解决一些问题(例如删除不必要的 new 和正确表示嵌套结构)之前,不要将其部署到更大的应用程序中。

关于c++ - 发送包含其他结构的结构作为 ZeroMQ 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23671324/

相关文章:

C++:匿名结构的结构前向声明导致 "conflicting declaration"

c++ - 内联结构成员

JavaScript 的 Ruby 范围的等效代码

c++ - Qt OpenGL 磅值

c++ - 有没有更好/更有效的方法来存储大型数组

python - (A, B) 和 (C,) 之间的 Minkowski 距离

javascript - 是否可以在数组引用中回显变量值

c - 如果该结构作为数组存在,是否可以仅从该结构发送一个变量?

c - 没有标签的结构

arrays - 在 golang 中使用 neast 和数组创建高级结构