Я создаю реализацию HDFS на С++, используя ONCRPC и Google Protobuf. Проблема, с которой я сталкиваюсь, заключается в том, что я отправляю объект protobuf с несколькими заполненными полями (отправка сериализованной строки, анализ ее на принимающей стороне), однако на принимающей стороне ошибочно говорится, что одно из полей имеет не установлено/не существует.
Это часть моего файла hdfs.proto:
message AssignBlockRequest {
optional int32 handle = 1; // obtain using call to OpenFile
}
message AssignBlockResponse {
optional int32 status = 1;
optional BlockLocations newBlock = 2;
}
message BlockLocations {
optional int32 blockNumber = 1;
repeated DataNodeLocation locations = 2;
}
message DataNodeLocation {
optional string ip = 1;
optional int32 port = 2;
}
Я использую это в «клиентском» приложении, чтобы запросить у «сервера namenode» новый блок и список узлов данных, на которые он может отправлять данные для записи.
Итак, в моем клиенте:
AssignBlockResponse assignnewblock_ ( int fhandle, CLIENT* clnt ) {
AssignBlockRequest req;
req.set_handle(fhandle);
//send request to nn
string str;
req.SerializeToString(&str);
static char *cstr = new char[str.length() + 1];
memcpy(cstr, str.c_str(), str.length()+1);
char **result_abreq;
result_abreq = assignblock_1( &cstr, clnt );
//handle response
AssignBlockResponse rsp;
string str_arg (*result_abreq);
rsp.ParseFromString(str_arg);
cout << "NN RETURNED : " << rsp.status() << " " << rsp.has_newblock() << endl;
return rsp;
}
в то время как в моем namenode server.cc
char **
assignblock_1_svc(char **argp, struct svc_req *rqstp)
{
AssignBlockRequest req;
string str_arg (*argp);
req.ParseFromString(str_arg);
AssignBlockResponse rsp;
if ( DataNodeList.empty() ) { // no DN available
rsp.set_status (1);
}
else {
rsp.set_status (0);
int BL_NUM = 0;
vector<int> shuf;
BlockLocations bl;// = new BlockLocations;
bl.set_blocknumber(BL_NUM);
rsp.mutable_newblock()->CopyFrom(bl);
}
cout << "NN RETURNED : " << rsp.status() << " " << rsp.has_newblock() << endl;
string str;
rsp.SerializeToString(&str);
static char *cstr = new char[str.length() + 1];
memcpy(cstr, str.c_str(), str.length()+1);
return &cstr;
}
NN выводит «0 1», в то время как клиент при получении этого запроса типа AssignBlockResponse показывает «0 0», т. е. он получает правильный статус (проверено путем изменения статуса, установленного в сообщении AssignBlockResponse), но никогда не обнаруживает поле «newblock», отправленное server.cc к нему.
Любая помощь будет принята с благодарностью.
-- РЕДАКТИРОВАТЬ 1 --
Сериализация буфера протокола с наследованием. Производные классы пусты
Это может представлять интерес. Однако я все еще не могу заставить свой код работать.