簡體   English   中英

如何通過 fifo 為 IPC 使用 protobuf 的 SerializeToOstream 和 ParseFromIstream?

[英]How to use protobuf's SerializeToOstream and ParseFromIstream for IPC via fifo?

我有客戶端通過 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 函數中阻塞,程序的執行就不會再進一步​​了。 誰能告訴我如何正確地寫這個?

嘗試通過 ostream 的 .flush() 函數在“msg.SerializeToOstream(&pipeOut)”之后刷新 pipeOut。 關閉流會刷新它,這就是第一個代碼示例起作用的原因。 當您保持流打開並向其寫入小於流緩沖區大小的數據時,除非/直到寫入更多數據以填充緩沖區並提示發送或刷新,否則讀取端無法使用該數據操作完成。

事實證明,問題是我使用了錯誤的序列化方法,protobuff 不知道消息何時結束並等待消息的下一部分,直到管道關閉。 這就是代碼的第一個版本有效而​​第二個版本無效的原因。 我設法使用Delimiting Protobuf Messages修復了這種行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM