如何通过fifo将protobuf的SerializeToOstream和ParseFromIstream用于IPC?

时间:2019-04-15 12:31:10

标签: c++ linux stream protocol-buffers fifo

我有客户端将通过protobuf序列化的消息通过linux fifo发送到服务器。我在代码中使用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函数内部,并且程序的执行不再进行。有人可以告诉我如何正确编写吗?

2 个答案:

答案 0 :(得分:0)

尝试通过ostream的.flush()函数在“ msg.SerializeToOstream(&pipeOut)”之后刷新pipeOut。关闭流将其冲洗掉,因此这就是第一个代码示例起作用的原因。当您保持流打开并向其中写入小于流缓冲区大小的数据时,则读侧将无法使用该数据,除非/直到写入更多数据以填充缓冲区并提示其发送或刷新操作完成。

答案 1 :(得分:0)

事实证明,问题在于我使用了错误的序列化方法,并且probuff不知道消息何时结束,并等待消息的下一部分直到管道关闭。因此,第一个版本的代码有效,而第二个版本的代码无效。我设法使用Delimiting Protobuf Messages来解决此问题。