c# - protobuf-csharp-端口

标签 c# .net networkstream protocol-buffers

我正在使用 Jon Skeet 的(优秀的)谷歌 Protocol Buffers 端口到 C#/.Net。

为了练习,我编写了一个虚拟的 Instant Messenger 应用程序,它可以通过套接字发送一些消息。我有一个消息定义如下:-

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 消息,控制也不会返回到调用方法。

如有任何建议,我们将不胜感激,

私服

最佳答案

很抱歉花了一些时间来回答这个问题。正如 Marc 所说, Protocol Buffer 没有终止符,除非嵌套,否则它们没有长度前缀。但是,您可以自己添加长度前缀。如果您查看 MessageStreamIterator 和 MessageStreamWriter,您会看到我是如何做到这一点的 - 基本上我假装我在消息中间,将嵌套消息写为字段 1。不幸的是,当阅读消息,我必须使用内部细节 (BuildImpl)。

现在有另一个 API 可以执行此操作:IMessage.WriteDelimitedToIBuilder.MergeDelimitedFrom。这可能是你现在想要的,但我似乎记得它在检测流的结尾方面有一个小问题(即当没有另一条消息可读时)。我不记得目前是否有针对它的修复程序——我感觉它在 Java 版本中发生了变化,我可能还没有移植这个变化。无论如何,这绝对是值得关注的领域。

关于c# - protobuf-csharp-端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3585562/

相关文章:

c# - 从 C# 源文件中提取属性名称

c# - 如何以精确的时间运行函数?

c# - 如何对从 NetworkStream 派生的类进行单元测试?

c# - WPF 媒体元素的背景图像

c# - 抛出 ArgumentNullException

c# - 加密的 NetworkStream 卡在 ReadLine() 上

.net - 如何将TCPClient和NetworkStream移植到Silverlight?

c# - 如何将 NetSuite 中的客户 priceLevel 设置为空白/空值?

c# - 如何从 ElementHandle 中获取文本?

c# - 使用 Json.NET 反序列化一个空数组