#c #linux #stream #protocol-buffers #fifo
#c #linux #поток #буферы протокола #fifo
Вопрос:
У меня есть клиент, который отправляет сообщения, сериализованные protobuf, на сервер через linux fifo. Я использую ifstream и ofstream в своем коде для операций ввода-вывода.
Если я напишу так:
//client
Client::request() {
std::ofstream pipeOut;
pipeOut.open(outputPipeName);
msg.SerializeToOstream(amp;pipeOut);
pipeOut.close();
...
}
//server
Server::process_requests() {
std::ifstream pipeIn;
while(isRunning) {
pipeIn.open(inputPipeName);
msg.ParseFromIstream(amp;pipeIn);
pipeIn.close();
...
}
}
все работает отлично. Но я не хочу постоянно открывать и закрывать потоки. Вместо этого я хочу написать что-то вроде этого:
//client
class Client {
std::ofstream pipeOut;
};
Client::Client() {
pipeOut.open(outputPipeName);
}
Client::~Client() {
pipeOut.close();
}
Client::request() {
msg.SerializeToOstream(amp;pipeOut);
...
}
//server
Server::process_requests() {
std::ifstream pipeIn;
pipeIn.open(inputPipeName);
while(isRunning) {
msg.ParseFromIstream(amp;pipeIn);
...
}
pipeIn.close();
}
но с этим кодом сервер блокируется внутри функции ParseFromIstream, и выполнение программы прекращается. Может кто-нибудь, пожалуйста, скажите мне, как это правильно написать?
Ответ №1:
Попробуйте сбросить pipeOut после «msg.SerializeToOstream (amp;pipeOut)» с помощью функции ostream .flush(). Закрытие потока сбрасывает его, поэтому первый пример кода работает. Когда вы оставляете поток открытым и записываете в него данные меньше, чем размер буфера потока, эти данные не становятся доступными для стороны чтения, пока / пока не будет записано больше данных для заполнения буфера и запроса на его отправку ИЛИ не будет выполнена операция сброса.
Комментарии:
1. Это было первое, о чем я подумал, но нет. Я написал в ответе, в чем проблема.
Ответ №2:
Как оказалось, проблема заключалась в том, что я использовал неправильный метод для сериализации, и protobuff не знал, когда сообщение закончится, и ждал следующей части сообщения, пока канал не был закрыт. Вот почему первая версия кода работала, а вторая — нет. Мне удалось исправить это поведение, используя разделительные сообщения Protobuf.