如何检测协议缓冲区消息何时完全接收?这是我的另一个问题的一个分支。想看就看,没必要。基本上,我意识到为了在大消息上有效地使用C#的BeginReceive(),我需要(a)首先读取数据包长度,然后准确读取那么多字节,或者(b)使用数据包结束分隔符.我的问题是,这些都存在于协议缓冲区中吗?我没有使用过它们,但文档中似乎没有长度标头或分隔符。如果没有,我该怎么办?我应该构建消息,然后使用长度标头/EOP定界符作为前缀/后缀吗?您需要在协议中包含大小或结束标记。基于流的套接字(TCP/IP)除了支持任意分解为单个数据包(并且数据包在传输过程中也可能溢出)的不确定八位字节流之外,不构建任何东西。一种简单的方法是为每个“消息”设置一个固定大小的标头,包括协议版本和有效负载大小以及任何其他固定数据。然后是消息内容(payload)。或者,可以添加带有校验和甚至加密签名的消息页脚(固定大小)(取决于您的可靠性/安全性要求)。知道负载大小后,您就可以继续读取足够多的字节来读取剩余的消息(如果读取完成的次数较少,则对剩余的字节执行另一次读取,直到收到整个消息)。使用结束消息指示符也可以,但是您需要定义如何处理包含相同八位字节序列的消息……对于迟到表示歉意。我是protobuf-net的作者,它是C#实现之一。对于网络使用,您应该考虑“[De]SerializeWithLengthPrefix”方法-这样,它会自动为您处理长度。源代码中有一些示例。我不会详细介绍旧帖子,但如果您想了解更多信息,请添加评论,我会尽快回复您。我同意Matt的观点,在ProtocolBuffers中标头比页脚更好,主要是因为,由于PB是一个二进制协议,因此提出一个也不是有效消息序列的页脚是有问题的。许多基于页脚的协议(通常是EOL协议)之所以有效,是因为消息内容在定义的范围内(通常是0x20–0x7FASCII)。一个有用的方法是让你的最低级代码只从套接字读取缓冲区并将它们呈现给一个框架层,该框架层组装完整的消息并记住部分消息(我在这里提出一种异步方法(使用CCR),尽管线路协议).为了保持一致性,您始终可以将消息定义为具有三个字段的PB消息:长度为固定整数,类型为枚举,以及包含实际数据的字节序列。这使您的整个网络协议保持透明。TCP/IP和UDP数据包都包含一些对其大小的引用。IP报头包含一个16位字段,指定IP报头的长度和以字节为单位的数据。TCP标头包含一个4位字段,以32位字指定TCP标头的大小。UDP报头包含一个16位字段,指定UDP报头的长度和以字节为单位的数据。事情是这样的。使用Windows中的标准纯套接字,您将看不到IP/TCP/UDP标头,无论您是使用C#中的System.Net.Sockets命名空间还是Win32中的本机Winsock。这些标头被剥离,以便您在读取套接字时得到的是实际有效负载,即发送的数据。我所见和所做的所有套接字的典型模式是,您在要发送的数据之前定义一个应用程序级标头。此标头应至少包含要遵循的数据大小。这将允许您完整地阅读每条“消息”而无需猜测其大小。你可以随心所欲地玩它,例如同步模式、CRC、版本、消息类型等,但“消息”的大小才是你真正需要的。对于它的价值,我建议使用标头而不是数据包结束定界符。我不确定EOP定界符是否有明显的缺点,但标头是我见过的大多数IP协议使用的方法。此外,对我来说,从头开始处理消息似乎更直观,而不是等待某些模式出现在我的流中以指示我的消息已完成。编辑:我刚刚意识到GoogleProtocolBuffers项目。据我所知,它是WCF的二进制序列化/反序列化方案(我确信这是一种过度简化)。如果您使用的是WCF,则不必担心要发送的消息的大小,因为WCF管道会在幕后处理这个问题,这可能就是为什么您不会在协议。缓冲文件。然而,在套接字的情况下,如上所述,了解尺寸会有很大帮助。我的猜测是您将使用ProtocolBuffers来序列化您的数据,然后在发送之前完成您放置的任何应用程序标头。在接收端,您将提取标头,然后反序列化消息的其余部分。以上就是C#学习教程:如何检测protocolbuffer消息接收完毕?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
