protobuf-csharp 端口
Posted
技术标签:
【中文标题】protobuf-csharp 端口【英文标题】:protobuf-csharp-port 【发布时间】:2010-08-27 15:12:35 【问题描述】:我正在使用 Jon Skeet 的(优秀的)将 Google 协议缓冲区移植到 C#/.Net。
为了练习,我编写了一个虚拟即时通讯应用程序,它通过套接字发送一些消息。我有一个消息定义如下:-
message InstantMessage <br/>
required string Message = 1;<br/>
required int64 TimeStampTicks = 2; <br/>
当发送者序列化消息时,它发送的非常优雅:-
...
InstantMessage.Builder imBuild = new InstantMessage.Builder();
imBuild.Message = txtEnterText.Text;
imBuild.TimeStampTicks = DateTime.Now.Ticks;
InstantMessage im = imBuild.BuildPartial();
im.WriteTo(networkStream);
...
这很好用。但另一方面,我无法让ParseFrom
工作。
我想使用:-
InstantMessage im = InstantMessage.ParseFrom(networkStream);
但是我不得不将它读取到字节,然后从这里解析它。由于多种原因,这显然不是理想的。当前代码是:-
while (true)
Byte[] byteArray = new Byte[10000000];
int intMsgLength;
int runningMsgLength = 0;
DateTime start = DateTime.Now;
while (true)
runningMsgLength += networkStream.Read(byteArray, runningMsgLength, 10000000 - runningMsgLength);
if (!networkStream.DataAvailable)
break;
InstantMessage im = InstantMessage.ParseFrom(byteArray.Take(runningMsgLength).ToArray());
当我尝试使用ParseFrom
时,即使我知道在线上有有效的 GB 消息,控制也不会返回到调用方法。
如有任何建议,我们将不胜感激,
私服
【问题讨论】:
Dataavailable 在这里是一个糟糕的选择,顺便说一句。它不会告诉您任何有关实际数据的信息。 明天会调查这个。今晚太累了。 【参考方案1】:很抱歉花点时间来回答这个问题。正如 Marc 所说,协议缓冲区没有终止符,除非它们是嵌套的,否则它们没有长度前缀。但是,您可以自己添加长度前缀。如果您查看 MessageStreamIterator 和 MessageStreamWriter,您会看到我是如何做到这一点的 - 基本上我假装我在消息中间,将嵌套消息写为字段 1。不幸的是,当阅读消息,我必须使用内部详细信息 (BuildImpl)。
现在有另一个 API 可以执行此操作:IMessage.WriteDelimitedTo
和 IBuilder.MergeDelimitedFrom
。这可能是您目前想要的,但我似乎记得在检测流结束方面存在一个小问题(即当没有其他消息要读取时)。我不记得目前是否有修复它 - 我感觉它在 Java 版本中发生了变化,我可能还没有移植这个变化。无论如何,这绝对是值得关注的领域。
【讨论】:
乔恩,对于迟到的回复深表歉意 - 我一直在参加培训课程。谢谢你的提示——我看了一眼,我相信通过这个解释我可以弄清楚。再次感谢,我真的很感激。私服【参考方案2】:Protobuf 没有终止符 - 所以要么关闭流,要么使用您自己的长度前缀等。Protobuf-net 通过 SerializeWithLenghtPrefix / DeserializeWithLengthPrefix 轻松公开这一点。
简单地说:没有这个,它就无法知道每条消息在哪里结束,所以一直尝试读取到流的末尾。
【讨论】:
谢谢 Marc,我不清楚您在哪里看到 SerializeWithLengthPrefix 及其相应的 Derserialize...您是说我需要在执行操作之前调用 InstantMessage 对象上的方法:im.WriteTo(networkStream ); ?再次感谢 @phil - protobuf-net 是一个不同的实现,但同样的方法应该可以工作。在 Jon 的版本中可能存在一个现有方法:我不确定。以上是关于protobuf-csharp 端口的主要内容,如果未能解决你的问题,请参考以下文章
Jmeter protobuf 测试。无法读取 Protobuf 消息