Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 检查已解析的协议缓冲区(Protobuf)proto3消息是否有效_C++_Validation_Parsing_Serialization_Protocol Buffers - Fatal编程技术网

C++ 检查已解析的协议缓冲区(Protobuf)proto3消息是否有效

C++ 检查已解析的协议缓冲区(Protobuf)proto3消息是否有效,c++,validation,parsing,serialization,protocol-buffers,C++,Validation,Parsing,Serialization,Protocol Buffers,我目前需要通过网络传输给定类型的Protobuf消息Foo,并在接收时进行处理 我正在使用Protobuf3.5.1和proto3语言 在接待时,我做以下工作: 创建预期类型的空实例Foo(通过工厂方法,因为它可能会更改) 解析来自CodedInputStream(根据从网络接收的数据构造)的消息 验证解析是否已成功 下面是一段说明具体问题的代码片段: // Create the empty Protobuf message of the EXPECTED type. std::shared_p

我目前需要通过网络传输给定类型的Protobuf消息
Foo
,并在接收时进行处理

我正在使用Protobuf3.5.1和
proto3
语言

在接待时,我做以下工作:

  • 创建预期类型的空实例
    Foo
    (通过工厂方法,因为它可能会更改)
  • 解析来自
    CodedInputStream
    (根据从网络接收的数据构造)的消息
  • 验证解析是否已成功
  • 下面是一段说明具体问题的代码片段:

    // Create the empty Protobuf message of the EXPECTED type.
    std::shared_ptr<google::protobuf::Message> message = std::make_unique<Foo>();
    
    // Create the CodedInputStream from the network data.
    google::protobuf::io::CodedInputStream stream{receive_buffer_.data(), static_cast<int>(bytes_transferred)};
    
    if (message->ParseFromCodedStream(&stream) && stream.ConsumedEntireMessage() && message->IsInitialized()) {
      // Message is of correct type and correctly parsed.
    } else {
      // Message is NOT VALID.
      // TODO: This does not work if sending a message of type `Bar`.
    }
    
    我还没有找到一种方法来检测收到的Protobuf消息类型是否“有效”


    因此,我的问题是:如何安全地检测
    Foo
    的解析实例是否有效,以及它是否是另一种(结构类似但完全不同)Protobuf消息类型的实例?我是否需要手动添加作为字段发送的消息的名称(这很愚蠢,但应该可以使用)?

    您可以使用
    反射
    描述符
    ,而不是使用名称定义附加字段。Protobuf编码格式不是自描述的。基本上,任何消息的二进制编码都可以成功解码为任何其他消息;后者最终可能会丢失和/或未知字段。双方必须以某种方式就交换的消息类型达成一致,通常是通过记录通信协议。为什么当另一方期望
    Foo
    时,另一方再次发送
    Bar
    ?@IgorTandetnik我知道Protobuf不是自描述的,但我认为可能有一种功能可以检测这种情况,因为我们讨论的是不同的类型(不是缺少/未知的字段)。发送方和接收方之间的合同定义明确。我们在这里谈论的不是功能性,而是非功能性软件质量,即使软件对无效/格式错误的输入数据具有鲁棒性。依我看,这并不是一个特别的要求。如果没有内置功能,我将使用字段方法,并在两侧使用
    Descriptor::full_name()
    。@Florian不存在这样的功能,因为它不可能实现。消息基本上是可互换的,只要它们没有冲突的导线类型预期(例如,字段2是一个字符串,另一个是变量)。那么,格式错误的数据可能包含正确的
    全名,然后在其余字段中成为垃圾。所有protobuf解析器都知道,
    Bar
    的二进制表示形式仅仅是
    Foo
    的一个不同(更新或更旧)版本-protobuf专门设计为在面对协议演变时具有健壮性。
    message Foo {
    
      First first = 1;
    
      oneof second {
    
        A a = 2;
        B b = 3;
      }
    }
    
    message Bar {
    
      First first = 1;
    
      oneof second {
    
        C c = 2;
        D d = 3;
      }
    }