使用消息队列在进程之间传递消息

时间:2010-11-25 09:04:53

标签: c++ posix

我有要求使用消息队列在两个进程之间进行通信。一个进程将请求发送到另一个进程,其他进程发送响应。

例如,其中一个请求列出了进程打开的所有文件名。我已经将接口结构设为

 #define LIST_NAMES   1
 #define LIST_FILE_NAMES_RESP  2

 struct sFileStruct {
  unsigned int  uiCommand;
  unsigned long ulNoOfBytes; // Number of bytes to be parsed in cha* pointer below
  char*         pRecvData;   // file names packed here in response.
 };


 sFileStruct inData;
 // I am filling the data.
 int inSize = sizeof(inData);

 mq_send(m_qSendDesc, (char*)&inData, inSize, inPriority);

我认为上面设计的问题是因为文件名legth正在改变char *指向数据的指针是不同的,但结构的大小总是不变的,所以接收器不接收所有数据,接收器在访问char时崩溃*指针。

我想在一个mq_send中发送完整数据,并且不希望在结构内部有静态数组。有没有其他方法使用消息队列,我们​​可以实现这一点。

请提供您的意见。 谢谢

3 个答案:

答案 0 :(得分:3)

Receiver正在崩溃,因为它无法访问您的指针,该指针仅可供发件人程序使用。您需要将实际数据发送到消息队列而不是指针。

答案 1 :(得分:1)

你可以在mq_send()上创建一个包含char缓冲区的包装器。

您发送的每条消息都会被序列化到此缓冲区中,然后您将其传递给mq_send,其长度必须为 - sizeof(int)+ sizeof(long)+ strlen(pRecvData)。

接收器将读取此数据并将其反序列化为sFileStruct。

使用std :: string而不是char *的恕我直言会更好。

示例代码(未经测试):

class MQWrapper
{
    std::string m_strBuffer;
public:
    int Send( const sFileStruct& sfs )
    {
        m_strBuffer.clear();
        m_strBuffer.append( static_cast<const char*> & sfs.uiCommand, sizeof(sfs.uiCommand) );
        m_strBuffer.append( static_cast<const char*> & sfs.ulNoOfBytes, sizeof(sfs.ulNoOfBytes) );
        m_strBuffer.append( sfs.pRecvData ); // only if it's zero-terminated string!!!

        return mq_send(m_qSendDesc, m_strBuffer.c_str(), m_strBuffer.length(), inPriority);
    }


    char m_receiveBUffer[ BUFFER_SIZE ];

    int Receive( sFileStruct& sfs )
    {
        int res = mq_receive( m_qSendDesc, receiveBUffer, BUFFER, outPriority );
        if( res < 0 )
            return res;
        if( res < sizeof(int) + sizeof(long) )
            return -1000; // malformed message
        sfs.uiCommand = * ( static_cast<unsigned int*> (m_receiveBUffer[0]) );
        sfs.ulNoOfBytes = * ( static_cast<long*> (m_receiveBUffer[ sizeof(int) ] ) );

        // I don't really use this style in my work and not sure how to use it
        // str::string would be much easier
        int stringLen = res - sizeof(int) - sizeof(long);
        sfs.pRecvData = new char [ stringLen + 1 ]; // you have to delete [] it later
        if( stringLen > 0 )
            strcpy( sfs.pRecvData, receiveBUffer + sizeof(int) + sizeof(long), stringLen );
        ss.pRecvData[ stringLen ] = '\0'; // null terminator
        return 0;
    }
};

答案 2 :(得分:0)

mq_send的第二个参数不应该是const char *值吗?但是你传递了一个自定义编写的结构。我会编写一些代码来序列化或将结构转换为const char *,然后使用strlen获取其长度并将这两个值作为第二个和第三个参数传递给mq_send。