Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.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解析器c++;_C++_Event Handling_Protocol Buffers - Fatal编程技术网

C++ 将数据流式传输到protobuf解析器c++;

C++ 将数据流式传输到protobuf解析器c++;,c++,event-handling,protocol-buffers,C++,Event Handling,Protocol Buffers,上下文 我正在C++中编写一个事件驱动的应用服务器。我想使用谷歌协议缓冲区来移动我的数据。因为服务器是事件驱动的,所以连接处理程序API基本上是一个回调函数,它让我知道当另一个N字节的缓冲区从客户端到达时 问题 作为protobuf的完全初学者,我的问题是:是否有可能以某种方式诱使protobuf接受组成一个完整消息所需的许多缓冲区,以方便“流解析器”,而不是等待整个数据首先到达一个临时缓冲区 换句话说,我想要这个: …而不是这个: 回答 答案与完整的代码是特别感谢 不,这是不可能的 Proto

上下文

我正在C++中编写一个事件驱动的应用服务器。我想使用谷歌协议缓冲区来移动我的数据。因为服务器是事件驱动的,所以连接处理程序API基本上是一个回调函数,它让我知道当另一个N字节的缓冲区从客户端到达时

问题

作为protobuf的完全初学者,我的问题是:是否有可能以某种方式诱使protobuf接受组成一个完整消息所需的许多缓冲区,以方便“流解析器”,而不是等待整个数据首先到达一个临时缓冲区

换句话说,我想要这个:

…而不是这个:

回答


答案与完整的代码是特别感谢

不,这是不可能的

Protobuf解析器是一个递归下降解析器,这意味着它的相当一部分状态存储在堆栈上。这使得它很快,但这意味着除了暂停整个线程外,没有办法暂停中间的解析器。如果你的应用程序是非阻塞的,你只需要缓冲字节,直到你有一个完整的消息来解析


也就是说,这并不像听起来那么糟糕。请记住,消息的最终解析表示形式(即内存中的消息对象)比wire表示形式大得多。因此,与您稍后将要使用它进行的操作相比,您几乎不会在缓冲上浪费内存。事实上,在解析之前,如果你不保存一个大的被解析的对象,它就在等待数据到达的时候,那么就可以推迟解析了。

是的,这是可能的,我已经在JavaScript中完成了,但是这个设计可以移植到C++。

从客户端()到达的
数据是否应该提供完整的消息内容?否则,您将需要一个传输层来完成接收流中的消息内容(例如,通过前缀消息内容长度等)。这就是这个问题的重点。它不包含完整消息的数据,但只包含其中的一小部分。嗨,Kenton,Protobuf解析器版本3仍然是这样吗?@user1158559我的理解是proto3不会改变低级解析的任何内容。它主要添加(和删除)各种高级语言特性。也就是说,proto3是在我离开谷歌后开发的,我还没有密切关注它。
//Event API. May be called multiple times for each protobuf message
bool data_arrived_from_client(void *buf,size_t len){
    my_protobuf.parse_part(buf,len); // THIS IS THE GROSSLY SIMPLIFIED SEMANTIC OF WHAT I WANT
    message_size+=len;
    if(message_size>COMPLETE_BUFFER_SIZE){
        use_complete_protobuf();
        return true;
    }
    return false;
}
//Event API. May be called multiple times for each protobuf message
bool data_arrived_from_client(void *buf,size_t len){
    my_temp_buffer.append_data(buf,len);
    message_size+=len;
    if(message_size>COMPLETE_BUFFER_SIZE){
        my_protobuf.ParseFromArray(my_temp_buffer.data_ptr(),my_temp_buffer.size());
        use_complete_protobuf();
        return true;
    }
    return false;
}