阅读使用boost ::支持ASIO :: read_async的Protobuf对象(Readin

2019-09-17 22:23发布

我写使用Boost ASIO的应用程序,其中客户端以及使用谷歌原缓冲区序列化的服务器交换消息。 我不知道什么是被发送的在网络上连载消息的大小。 看来,原BUF对象没有任何分隔符。

这里有.proto文件的内容。

 package tutorial;

message Person {
        required string name = 1;
        required int32 id = 2;
        optional string email = 3;
}

下面是我从服务器写入

        tutorial::Person p;
        p.set_name("abcd pqrs");
        p.set_id(123456);
        p.set_email("abcdpqrs@gmail.com");
        write(p);

        boost::asio::streambuf b;
        std::ostream os(&b);
        p.SerializeToOstream(&os);
        boost::asio::async_write(socket_, b,
                        boost::bind(&Server::handle_write, this,
                                boost::asio::placeholders::error));

在客户端,我阅读了上面使用boost ::支持ASIO :: async_read发送的消息。 我如何找出的值arg被设置成一个参数boost::asio::transfer_at_least ,在下面的代码?

 boost::asio::async_read(socket_, response_,
                            boost::asio::transfer_at_least(arg),
                            boost::bind(&Client::handle_read_header, this,
                                    boost::asio::placeholders::error));

要不然我怎么确保的boost ::阅读整个对象后async_read回报?

Answer 1:

正确,protobufs没有分隔。 有没有知道哪里的消息只从字节流结束 - 即使你已经看到所有你知道的,也许还有更多的重复元素的字段或某人已经扩展了你不知道某个字段原。

一个常见的解决方案是用长度前缀的帧(通常编码为VarInt S)。 性LevelDB和SZL都使用这种方法,例如。 一个VarInt可以明确地解码逐字节,然后你知道有多少更多的字节解析您的完整的消息之前阅读。



文章来源: Reading Protobuf objects using boost::asio::read_async