rabbitmq 消息长度_如何从消息队列接收动态长度数据?

本文介绍了如何在使用RabbitMQ时处理动态长度的消息数据。通过使用结构体hack配合`msgrcv`和`msgsnd`函数,确保正确读取和发送包含std::string的数据。文章强调了在考虑对齐问题的同时,利用std::vector来动态调整缓冲区大小,从而实现高效的消息读写操作。
摘要由CSDN通过智能技术生成

您无法将指向包含std::string成员的结构的指针传递给msgrcv,这违反了接口合约。

传递给msgrcv的第二个参数需要指向一个缓冲区,该缓冲区具有足够的空间来存储struct { long mtype; char mdata[size]; };格式的'普通'C结构,其中size是msgrcv的第三个参数。

不幸的是,由于可能存在对齐问题,确定此缓冲区的大小可能取决于size,但您必须假定它不在提供此类接口的系统上。您可以使用标准的offsetof宏来帮助确定这个大小。

由于vector连续存储其组件,因此一旦知道缓冲区的大小,就可以调整char的vector大小,并使用它来保存缓冲区。使用vector可以手动解除缓冲区对free或delete[]缓冲区的义务。

你需要做这样的事情。

std::string RecvMessage()

{

extern size_t size; // maximum size, should be a parameter??

extern int MSGQ_ID; // message queue id, should be a parameter??

extern long MSG_ID; // message type, should be a parameter??

// ugly struct hack required by msgrcv

struct RawMessage {

long mtype;

char mdata[1];

};

size_t data_offset = offsetof(RawMessage, mdata);

// Allocate a buffer of the correct size for message

std::vector msgbuf(size + data_offset);

ssize_t bytes_read;

// Read raw message

if((bytes_read = msgrcv(MSGQ_ID, &msgbuf[0], size, MSG_ID, 0)) < 0)

{

throw MsgRecvFailedException();

}

// a string encapsulates the data and the size, why not just return one

return std::string(msgbuf.begin() + data_offset, msgbuf.begin() + data_offset + bytes_read);

}换个角度来说,你只需要按照msgsnd接口的要求将数据打包到struct黑客兼容数据数组中。正如其他人指出的那样,它不是一个好的界面,但是对实现定义的行为和对齐关注点进行了修饰,应该这样做。

例如

void SendMessage(const std::string& data)

{

extern int MSGQ_ID; // message queue id, should be a parameter??

extern long MSG_ID; // message type, should be a parameter??

// ugly struct hack required by msgsnd

struct RawMessage {

long mtype;

char mdata[1];

};

size_t data_offset = offsetof(RawMessage, mdata);

// Allocate a buffer of the required size for message

std::vector msgbuf(data.size() + data_offset);

long mtype = MSG_ID;

const char* mtypeptr = reinterpret_cast(&mtype);

std::copy(mtypeptr, mtypeptr + sizeof mtype, &msgbuf[0]);

std::copy(data.begin(), data.end(), &msgbuf[data_offset]);

int result = msgsnd(MSGQ_ID, &msgbuf[0], msgbuf.size(), 0);

if (result != 0)

{

throw MsgSendFailedException();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值