Protobuf需要一个网络数据包头吗?

10

我正在使用'protobuf'为使用TCP的C/S网络程序打包数据。

以下是客户端的步骤:

1. 将数据封装到“protobuf”中

2. 获取打包的字节数并构造长度前缀帧

3. 将帧+打包数据写入套接字

服务器的步骤如下:

1. 从套接字读取长度前缀帧并获取长度 N

2. 从套接字读取 N 字节并将数据填充到 protobuf 实例中

3. 通过“key”从 protobuf 中获取“value”

我认为这似乎有点复杂,是否有一种自动生成长度前缀帧的方法,这样我就不需要手动构造了。还有其他可以使代码更简洁的方法吗?


你的问题含糊不清。你是在使用TCP?UDP?IP?还是其他网络协议?很难确定protobuf是什么。它是一个结构体还是只是一块数据?大多数C/S应用程序都需要一些帮助来确定要发送或接收的数据的合理性。你需要更具体并展示代码。 - Ahmed Masud
谢谢您的建议,我会让它更加清晰明了。'protobuf' 特指谷歌开源项目。 - Shawn
2个回答

6
使用protobuf,假设您正在通过同一管道发送多个消息,那么:是的 - 您需要将长度作为前缀,否则它将要读取流的末尾。 protobuf确实包括一些基本的RPC存根,但它们使用的RPC实现不是OSS项目的一部分,因此不可用。不过,这里列出了一些独立的protobuf RPC堆栈。
个人而言,我倾向于假装数据序列是“重复”序列的一部分 - 即以“field 1,string”(又名0a)为前缀,并将长度编码为“varint”。这意味着整个网络流是有效的protobuf流。可能只是我的强迫症发作了。
一些实现可能包含有助于处理此问题的功能。例如,“protobuf-net”(.NET版本之一)具有SerializeWithLengthPrefix/DeserializeWithLengthPrefix方法,可以让库为您执行此操作(同时提供多种格式供您选择)。

4

我不知道这是否适合你的任务,但我建议你研究一下已经为你想要支持的语言编写的“rpc实现”之一。

https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md#rpc-implementations

例如,我在使用Java中的Netty时取得了良好的结果,因为Netty内置支持发送给定类型的MessageLite实例。http://docs.jboss.org/netty/3.2/guide/html/architecture.html#d0e1979

(我确信您的长度标头可以很好地完成工作,但是像Netty这样的框架将相对容易地添加支持异步“双向”IO、SSL、身份验证等功能)

希望对您有所帮助。


基于protobuf的RPC是一个好的解决方案。我仍然好奇是否有纯protobuf的解决方案。 - Shawn
那就是了。我认为这超出了protobuf本身的范围。它只是一种序列化机制,独立于传输或存储。许多传输机制(例如文件中的一个消息)不需要支持多个消息,也不需要提供自己的完整性检查机制。 - laher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接