Как использовать прототип SerializeToOstream и ParseFromIstream для IPC через fifo? - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть клиент, который отправляет сообщения, сериализованные protobuf, на сервер через linux fifo. Я использую ifstream и ofstream в своем коде для операций ввода-вывода.

Если я напишу так:

//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 голосов
/ 25 мая 2019

Как оказалось, проблема заключалась в том, что я использовал неправильный метод для сериализации, и протобуфф не знал, когда закончится сообщение, и ждал следующую часть сообщения, пока канал не был закрыт. Вот почему первая версия кода работала, а вторая - нет. Мне удалось исправить это поведение, используя Delimiting Protobuf Messages .

0 голосов
/ 16 мая 2019

Попробуйте сбросить pipeOut после "msg.SerializeToOstream (& pipeOut)" с помощью функции of's .flush ().Закрытие потока сбрасывает его, поэтому первый пример кода работает.Когда вы держите поток открытым и записываете в него данные размером меньше размера буфера потока, эти данные не становятся доступными для чтения, если / пока не будет записано больше данных для заполнения буфера и запроса его отправки ИЛИ сбросаоперация выполнена.

...