Загрузить файл на сервер, используя буфер протокола в C ++ - PullRequest
0 голосов
/ 02 апреля 2020

Моя цель - создать файл и затем использовать потоковое соединение для отправки файла на сервер с помощью gRPC ++. Может кто-нибудь подтвердить, работает ли приведенный ниже код для клиента?

Мой файл протока содержит один объект "байты"

message FileContent {
  bytes content = 1;
}

Код клиента

char *buffer = new char[2048];
// Open a stream-based connection with the gRPC server
std::unique_ptr<ClientWriter<FileContent> > writer(this->service_stub->Store(&context, &fileack));

// send the file name to the server
filecontent.set_content(filename);
std::cout << "Client: RPC call with File Name:" << filecontent.content() << endl;
writer->Write(filecontent);

// Get a file handle for the file we want to upload and the file length 

fileStream.open(filename, ios::binary);


while (!fileStream.eof())
{
     std::this_thread::sleep_for(std::chrono::milliseconds(100));
     filecontent.clear_content();
     fileStream.read(buffer,2048);
     filecontent.set_content(std::string(buffer, 2048));
     writer->Write(filecontent);
}

Код сервера

    Status Store(ServerContext* context, ServerReader<FileContent>* reader, FileAck* fileack) override {

 FileContent filecontent;
 ofstream fileStream;
 std::string serverfilepath;

 if (fileStream.is_open())
 {
     std::cout << "Reading Data";
     while (reader->Read(&filecontent))
     {
         std::cout << "Reading Data";
         fileStream << filecontent.mutable_content();
     }

     fileStream.close();
 }

 else
 {
    reader->Read(&filecontent);
    fileStream.open(serverfilepath, ios::binary);
 }

 return Status::OK;

}

1 Ответ

0 голосов
/ 02 апреля 2020

Тип protobuf bytes создает поле типа std::string на стороне C ++. Таким образом, ваш char *buffer неявно преобразуется в std::string.

. Проблема в том, что используемый для этого конструктор ожидает строку с нулевым символом в конце, но ваш buffer не имеет терминаторный байт (и не может, потому что он может содержать \0 байт в середине). Это может привести к тому, что конструктор std::string будет работать над концом буфера в поисках байта терминатора.

Чтобы это исправить, создайте std::string с длиной, явно указанной:

filecontent.set_content(std::string(buffer, 2048));
...