收到的Protobuf对象没有所有字段



我正在使用ONCRPC和Google Protobuf创建HDFS的c++实现。我面临的问题是,我正在发送一个填充了多个字段的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;
}

我在"客户端"应用程序中使用它来查询"名称节点服务器",以获取一个新块和一个数据节点位置列表,它可以向这些位置发送要写入的数据。

所以,在我的客户:

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服务器.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消息中设置的状态进行测试),但从未检测到服务器.cc发送给它的"newblock"字段。

如有任何帮助,我们将不胜感激。

--编辑1-

使用继承进行协议缓冲区序列化。派生类为空

这可能令人感兴趣。然而,我仍然无法使我的代码正常工作。

我在早期的协议缓冲区工作中遇到过这种情况。

不要序列化为字符串。serializeToArray首先构建了一个足够大的向量(在消息上调用ByteSize())

问题是,串行化的字节流包含一个零字节,当将char*转换为字符串时,它被解释为字符串的末尾。

这意味着您最终解析的是不完整的消息,因此缺少字段。

相关内容

  • 没有找到相关文章

最新更新