简体   繁体   English

protobuf的-CSHARP端口

[英]protobuf-csharp-port

I'm using Jon Skeet's (excellent) port of Google's Protocol Buffers to C#/.Net. 我正在使用Jon Skeet的(优秀)谷歌协议缓冲区端口到C#/ .Net。

For practice, I have written a dummy Instant Messenger app that sends some messages down a socket. 为了练习,我编写了一个虚拟的Instant Messenger应用程序,它可以在套接字上发送一些消息。 I have a message definition as follows:- 我的消息定义如下: -

message InstantMessage {<br/>
  required string Message = 1;<br/>
  required int64 TimeStampTicks = 2; <br/>
}

When the sender serialises the message, it sends it really elegantly:- 当发件人序列化邮件时,它会非常优雅地发送邮件: -

        ...
        InstantMessage.Builder imBuild = new InstantMessage.Builder();

        imBuild.Message = txtEnterText.Text;
        imBuild.TimeStampTicks = DateTime.Now.Ticks;

        InstantMessage im = imBuild.BuildPartial();

        im.WriteTo(networkStream);
        ...

This works great. 这非常有效。 But at the other end, I'm having trouble getting the ParseFrom to work. 但另一方面,我无法让ParseFrom工作。

I want to use:- 我想用: -

InstantMessage im = InstantMessage.ParseFrom(networkStream);

But instead I have had to read it to bytes and then parse it from here. 但相反,我必须将其读取为字节,然后从此处解析它。 This is obviously not ideal for a number of reasons. 出于多种原因,这显然不是理想的。 Current code is:- 目前的代码是: -

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());

When I try to use ParseFrom , control does not return to the calling method even when I know a valid GB message is on the wire. 当我尝试使用ParseFrom ,即使我知道有线GB消息ParseFrom ,控制也不会返回到调用方法。

Any advice would be gratefully received, 任何建议都会感激不尽,

PW PW

Sorry for taking a while to answer this. 很抱歉花了一些时间来回答这个问题。 As Marc says, protocol buffers don't have a terminator, and they aren't length prefixed unless they're nested. 正如Marc所说,协议缓冲区没有终结符,除非它们是嵌套的,否则它们不是长度前缀。 However, you can put on the length prefix yourself. 但是,您可以自己加上长度前缀。 If you look at MessageStreamIterator and MessageStreamWriter, you'll see how I do this - basically I pretend that I'm in the middle of a message, writing a nested message as field 1. Unfortunately when reading the message, I have to use internal details (BuildImpl). 如果你看一下MessageStreamIterator和MessageStreamWriter,你会看到我是怎么做的 - 基本上我假装我正处于消息中间,将嵌套消息写成字段1.不幸的是,在阅读消息时,我必须使用内部细节(BuildImpl)。

There's now another API to do this: IMessage.WriteDelimitedTo and IBuilder.MergeDelimitedFrom . 现在有另外一个API来执行此操作: IMessage.WriteDelimitedToIBuilder.MergeDelimitedFrom This is probably what you want at the moment, but I seem to remember there's a slight issue with it in terms of detecting the end of the stream (ie when there isn't another message to read). 这可能是你现在想要的,但我似乎记得它在检测流的结束方面存在一个小问题(即,当没有其他消息要读取时)。 I can't remember whether there's a fix for it at the moment - I have a feeling it's changed in the Java version and I may not have ported the change yet. 我不记得目前是否有一个修复程序 - 我感觉它在Java版本中已经改变了,我可能还没有移植过这个改变。 Anyway, that's definitely the area to look at. 无论如何,这绝对是值得关注的领域。

Protobuf has no terminator - so either close the stream, or use your own length prefix etc. Protobuf-net exposes this easily via SerializeWithLenghtPrefix / DeserializeWithLengthPrefix. Protobuf没有终止符 - 所以要么关闭流,要么使用自己的长度前缀等.Protobuf-net通过SerializeWithLenghtPrefix / DeserializeWithLengthPrefix轻松暴露这个。

Simply: without this, it can't know where each message ends, so keeps trying to read to the end of the stream. 简单地说:没有它,它无法知道每条消息的结束位置,因此不断尝试读取到流的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 protobuf-csharp-port 和 protobuf-net 如何选择 - How to choose between protobuf-csharp-port and protobuf-net 如何在 Windows 下在 Mono 上构建 protobuf-csharp-port - How to build protobuf-csharp-port on Mono under Windows protobuf-csharp-port是否支持Windows RT? - Does protobuf-csharp-port support Windows RT? 是否可以在protobuf-csharp-port中检测消息类型? - Is it possible to detect message type in protobuf-csharp-port? 使用带有protobuf-csharp-port的文件记录和重播人类可读的protobuf消息 - Record and replay human-readable protobuf messages using a file with protobuf-csharp-port 有没有办法将protobuf-csharp-port生成的类与servicestack.ormlite一起使用? - Is there way to use protobuf-csharp-port generated classes with servicestack.ormlite? protobuf-csharp-port这些工具最适合今天使用什么版本? - protobuf-csharp-port what version(s) of these tools are best to use today? protobuf-csharp-port-来自文件的流记录有点像LINQ-to-XML中的轴函数 - protobuf-csharp-port - streaming records from a file a bit like an axis function in LINQ-to-XML 协议缓冲区-protobuf-csharp-port:是否存在等效的JAVA API调用CodedInputStream.getBytesUntilLimit()? - Protocol Buffers - protobuf-csharp-port : Does the equivalent of JAVA API call CodedInputStream.getBytesUntilLimit() exist? Xamarin端口XCode到CSharp - Xamarin Port XCode to CSharp
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM