如何通过fifo使用protobuf的SerializeToOstream和ParseFromIstream进行IPC?



我有客户端通过linux fifo将protobuf序列化的消息发送到服务器。我在代码中使用ifstream和ofstream进行I/O操作。

如果我这样写:

//client
Client::request() {
  std::ofstream pipeOut;
  pipeOut.open(outputPipeName);
  msg.SerializeToOstream(&pipeOut);
  pipeOut.close();
  ...
}
//server
Server::process_requests() {
  std::ifstream pipeIn;
  while(isRunning) {
    pipeIn.open(inputPipeName);
    msg.ParseFromIstream(&pipeIn);
    pipeIn.close();
    ...
  }
}

一切都很完美。但我不想不断地打开和关闭溪流。相反,我想写这样的东西:

//client
class Client {
  std::ofstream pipeOut;
};
Client::Client() {
  pipeOut.open(outputPipeName);
}
Client::~Client() {
  pipeOut.close();
}

Client::request() {
  msg.SerializeToOstream(&pipeOut);
  ...
}
//server
Server::process_requests() {
  std::ifstream pipeIn;
  pipeIn.open(inputPipeName);  
  while(isRunning) {
    msg.ParseFromIstream(&pipeIn);
    ...
  }
  pipeIn.close();
}

但是有了这个代码服务器在 ParseFromIstream 函数中阻塞,程序的执行就不再进一步了。谁能告诉我如何正确写这个?

事实证明,问题是我使用了错误的方法进行序列化,protobuff 不知道消息何时结束,并等待消息的下一部分,直到管道关闭。这就是为什么代码的第一个版本有效,而第二个版本不起作用。我设法使用分隔 Protobuf 消息修复了此行为。

尝试在"msg.SerializeToOstream(&pipeOut("通过 ostream 的 .flush(( 函数。关闭流会刷新它,因此这就是第一个代码示例工作的原因。当您保持流打开并向其写入的数据小于流缓冲区大小时,读取端不会提供数据,除非/直到写入更多数据以填充缓冲区并提示发送或完成刷新操作。

相关内容

  • 没有找到相关文章

最新更新