我有客户端将通过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函数内部,并且程序的执行不再进行。有人可以告诉我如何正确编写吗?
答案 0 :(得分:0)
尝试通过ostream的.flush()函数在“ msg.SerializeToOstream(&pipeOut)”之后刷新pipeOut。关闭流将其冲洗掉,因此这就是第一个代码示例起作用的原因。当您保持流打开并向其中写入小于流缓冲区大小的数据时,则读侧将无法使用该数据,除非/直到写入更多数据以填充缓冲区并提示其发送或刷新操作完成。
答案 1 :(得分:0)
事实证明,问题在于我使用了错误的序列化方法,并且probuff不知道消息何时结束,并等待消息的下一部分直到管道关闭。因此,第一个版本的代码有效,而第二个版本的代码无效。我设法使用Delimiting Protobuf Messages来解决此问题。