发送字符串时提升消息队列崩溃

Posted

技术标签:

【中文标题】发送字符串时提升消息队列崩溃【英文标题】:boost message queue crashes when sending a string 【发布时间】:2016-09-22 10:08:17 【问题描述】:

我正在尝试使用 boost 进程间消息队列将字符串内容传递给另一个进程。传递整数时没有问题,但是当我想传递 std::string 下的缓冲区时,会引发异常

boost::interprocess_exception::library_error

代码如下。 这次崩溃的原因可能是什么?

  // SENDER process
  //
  message_queue::remove("messagequeue");

  //Create a message_queue.
  message_queue mq (create_only,"messagequeue",100,sizeof(char));
  std::string text("ciao");
  mq.send(text.data(), text.size(), 0);
  sleep(100);


  // RECV process
  //
  void get()
  
    message_queue mq(open_only,"messagequeue");
    unsigned int priority;
    message_queue::size_type recvd_size;

    std::string message;
    message.resize(100);
    mq.receive(&message[0], 100, recvd_size, priority);
    message.resize(recvd_size);
    std::cout << message << std::endl;

    sleep(100000);
  

  int main()
  
    boost:: thread t;
    t = boost::thread(get);
    t.join();
    return 1;
  

【问题讨论】:

我认为您的代码可能存在几个问题。发送text.size() 不会发送终止零。我也会避免在接收时使用message[0] 构造。如果您想这样做,请改用矢量。 .data() 也更干净。当您将向量转换为字符串时,也不要忘记终止零。 同样的问题。什么也没有变。在我的代码下面。 std::vector 数据; data.push_back('c'); data.push_back('i'); data.push_back('a'); data.push_back('o'); data.push_back('\n'); mq.send(data.data(), data.size(), 0); @AdrianRoman 没有终止 NUL(至少,没有有意义的 NUL,std::string 添加的 NUL 纯粹用于遗留互操作)。其实字符串里面可以有很多NUL字符 这是真的,无关紧要。如果您进行如下访问,您仍然可以溢出缓冲区:&amp;message[0]。 lakeweb 给出了正确答案。我只是简单地查看了代码并注意到地址使用情况,这可能很危险。这里不是这种情况,问题出在其他地方。 【参考方案1】:

在您创建消息队列的位置,您拥有sizeof( char ),但您试图将 4 个字符放入缓冲区中。追踪辱骂异常在:

   if (buffer_size > p_hdr->m_max_msg_size) 
      throw interprocess_exception(size_error);
   

在 message_queue.hpp 中。与:

bi::message_queue mq( bi::open_or_create,"messagequeue", 100, 4 );

它适用于“ciao”。

【讨论】:

它可能会或可能不会用 NUL 终止符填充。不管怎样,std::cout &lt;&lt; s; 很可能像std::cout.write(s.data(), s.size()) 一样简单地实现。从来没有涉及 NUL 终止符。它与大小有关,而不是 C++ 中的哨兵 嗨,sehe,根据this,缓冲区将在'string::resize'上填充空字符,而进程间只会对有效负载进行memcpy。那时,不需要第二次调整大小。我想你误读了我的意思,或者我不明白。 ciao 不会打印没有尾随字符,因为实际上缓冲区已清零。它打印时没有尾随字符,因为字符串的长度是 5 个字节(即使调整大小不会将缓冲区归零,它也不会打印尾随垃圾) 啊,我明白了。因为xsputn 使用字符串大小或空字符,以先出现的为准。谢谢。 嗨,嘿嘿,我的大脑一定很想与那个空终止符相关,所以我错过了阅读链接。我已删除该更新,因为它是错误的。再次感谢。

以上是关于发送字符串时提升消息队列崩溃的主要内容,如果未能解决你的问题,请参考以下文章

无法将消息发送到 weblogic 队列

IPC消息队列溢出后果

Spring Boot 与消息

RabbitMQ消息和队列的持久化

SpringBoot Spring和消息队列RabbitMQ

消息队列:RabbitMQ