c++ - Protobuf 声明我缺少必填字段,而我显然不是

标签 c++ c protocol-buffers

我正在编写一个使用 protobuf 作为序列化系统的轻量级服务器-客户端系统。我在 protobufs 提示缺少必填字段时遇到问题,但 1) 这些字段显然存在于数据流中,并且 2) 错误消息未识别缺少的字段。

首先是一段代码:

myMessages::DataRequest cData;  // this is declared outside of the function in the global
                                // so it can be reused each time to avoid unnecessary
                                // memory allocation. Per the documentation in protobufs
.
.
.

bool processStream(u_int8_t *pStream, u_int32_t dwLength)
{
try
{
    if (!cData.ParseFromArray(pStream, dwLength))
    {
        printf("Failed to parse data stream\n");
        hexdump(pStream, dwLength);
        return false;
    }
}
catch(exception e)
{
    printf("Exception in ParseFromArray: %s", e.what());
    hexdump(pStream, dwLength);
    return false;
}

这是我获取完整数据流并尝试获取 protobufs 对其进行解码的代码。大多数时候这工作正常。但是通过这段代码的每一次迭代我都会得到这个错误:

[libprotobuf ERROR google/protobuf/message_lite.cc:123] Can't parse message of type "myMessages.DataRequest" because it is missing required fields: 

作为失败的结果,我的代码吐出了这个,向我展示了提供给 protobuf 解析器的缓冲区:

Failed to parse data stream
000000: 08 86 ad 80 a5 f0 e7 aa e7 01 12 06 64 37 32 36  ............d726
000010: 31 37

DataRequest .proto 非常简单...

message DataRequest {
required uint64 timeStamp = 1;
required string strid= 2;
optional bool checkin= 3;

// event messages
repeated internalMessage1 iEvents = 5;
repeated internalMessage2 oEvents = 6;
repeated internalMessage3 eEvents = 7;
repeated internalMessage4 qEvents = 8;

// aux messages
repeated auxMessages auxEvents = 20;

这个 proto 表明唯一需要的字段是 1 和 2(分别是时间戳和 strid)。解码 hexdump 中显示的数据的有线格式,您可以清楚地看到两个必填字段都存在。此外,您可以看到重复的字段丢失了(所以这不像是我在其中一个字段中丢失了必填字段!)。

知道为什么 protobufs 在这里是个 SCSS 吗?

谢谢!

tjac.

最佳答案

事实证明,protobufs 不适合使用全局声明的变量跨多个线程使用。我遇到的错误是我的服务器正在处理多个数据流的结果。我将上面的 protobuf 处理程序代码声明为每个线程调用的独立函数。由于没有排他性检查,因为我正处于一个调用(例如 ParseFromArray)的中间,来自另一个线程的另一个调用可能正在修改对象内的数据。

长话短说,我没有注意多线程编程的基本租户,结果我注定要花几个小时试图弄清楚 protobufs 是如何失败的。我只能希望这对将来的其他人有所帮助。

关于c++ - Protobuf 声明我缺少必填字段,而我显然不是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18666369/

相关文章:

c - 免费后使用ASAN堆

Rust protobuf 序列化一团糟

c++ - 着色和调色板最佳拟合算法

c++ - 查找加起来等于特定数字倍数的数组子集的数量

c++ - 为什么这个 C++ 继承代码示例的行为是这样的

c - f(&a) 可以在 C 中运行吗?

c++ - 如何将在依赖项 CMake 项目中创建的 Protobuf 生成的 .h 文件正确导入父 CMake 项目?

c - 在 MIPS 目标系统上编译 protobuf-c 的问题

c++ - 通过类的成员搜索类的 vector

c++ - 替换版本信息资源