收到的 Protobuf 对象没有所有字段
Protobuf object received does not have all fields
我正在使用 ONCRPC 和 Google Protobuf 创建 HDFS 的 C++ 实现。我面临的问题是我正在发送一个填充了多个字段的 protobuf 对象(发送序列化字符串,在接收端从中解析),但是,在接收端它错误地表示其中一个字段具有没有 set/does 不存在。
这是我的 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;
}
我在 "client" 应用程序中使用它来查询 "namenode server" 的新块和它可以向其发送要写入的数据的数据节点位置列表。
所以,在我的客户中:
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;
}
在我的名称节点中 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 --
Protocol buffer serializing with inheritance. Derived classes are empty
这可能很有趣。然而,我仍然无法让我的代码工作。
我在早期使用协议缓冲区的工作中遇到过这个问题。
不要序列化到字符串。 serializeToArray 首先构建了一个足够大的向量(在消息上调用 ByteSize())
问题是您的序列化字节流包含一个零字节,在将 char* 转换为字符串时,它被解释为字符串结尾。
这意味着您最终解析了一条不完整的消息,因此缺少字段。
我正在使用 ONCRPC 和 Google Protobuf 创建 HDFS 的 C++ 实现。我面临的问题是我正在发送一个填充了多个字段的 protobuf 对象(发送序列化字符串,在接收端从中解析),但是,在接收端它错误地表示其中一个字段具有没有 set/does 不存在。
这是我的 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;
}
我在 "client" 应用程序中使用它来查询 "namenode server" 的新块和它可以向其发送要写入的数据的数据节点位置列表。
所以,在我的客户中:
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;
}
在我的名称节点中 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 --
Protocol buffer serializing with inheritance. Derived classes are empty
这可能很有趣。然而,我仍然无法让我的代码工作。
我在早期使用协议缓冲区的工作中遇到过这个问题。
不要序列化到字符串。 serializeToArray 首先构建了一个足够大的向量(在消息上调用 ByteSize())
问题是您的序列化字节流包含一个零字节,在将 char* 转换为字符串时,它被解释为字符串结尾。
这意味着您最终解析了一条不完整的消息,因此缺少字段。