2011-06-04 156 views
1

我是网络编程的新手,所以我有一个问题:在我的C++和C#之间发送一个整数是否安全(因为32有“endianess”问题)去做?通过网络传输int

在我的程序中,我将int转换为char(我知道它低于255)并发送它。不过,我想发32 int。我尝试了使用协议缓冲区的行为。我使用C++中的WriteVarint32和C#中的ProtoReader.ReadUInt32,但没有成功(C#中的例外)。我认为它会工作后,我读this

你会如此善良,并建议我在C++和C#应用程序之间发送一个整数的正确方法吗?如果你向我解释如何用协议缓冲区(在C#的情况下为protobuf-net)做到这一点,我会非常高兴。

+7

那么为什么16bit没有endianness和32bit的问题呢? bigendian/littleendian机器的16位数据将会有所不同。我建议你决定一种方法(例如协议缓冲区)并尝试一下,并询问你得到的问题。 – 2011-06-04 09:55:41

+0

@David varint编码工作在endianness周围(这是隐含的) – 2011-06-04 11:57:09

回答

0

如果您使用protobuf-net编写,WithLengthPrefix方法将为您执行此操作。我很乐意帮助(我是作者)。顺便说一句,它抛出一个例外的原因是varit值本身在protobuf流中通常不是有效的。如果传递0作为字段编号(或者传递一个更纯的protobuf流的正字段编号;但这是可选的),系统将在WithLengthPrefix的情况下覆盖此值。

碰巧在ProtoReader上有一个方法来读取一个孤立的varint(不用担心protobuf流语义),如果这样做对ProtoWriter是有用的,那么将它添加到ProtoWriter中将是微不足道的。

btw - 就PrefixStyle而言,Base128与varint相同。有些人更喜欢32位的前缀,与其他系统结婚 - 因此提供了一些其他系统。

+0

我想使用WithLengthPrefix。我的问题是我不知道我应该如何使用C++ Protobuf API来构造C#protobuf-net可以理解的前缀。 'Base128与varint相同' - 我尝试发送大小为varint。 C#引发System.IO.EndOfStreamException。前缀是只存在于protobuf-net中的想法。 C++实现甚至没有考虑到这个概念。 – 2011-06-04 22:14:40

+0

@主 - 的确如此。对于这个(在文档中)的策略只有一个简短的提及,其基本上是说“添加自己的长度”。重新EOF - 我重新部署了一个v2样本,我在之前的讨论中添加了一个v2样本(我相信) - 请检查您是否有当前版本。你能给出一个关于你的策略的简短的话:“我通过C++的消息是27字节,所以我写了[TODO:字节]作为前缀,然后是27字节” - 那么我应该能够看到你有什么。 – 2011-06-04 22:38:03

+0

消息测试{ required int32 id = 1; } 这是我想发送的消息。现在我设置id(用C++): 测试测试; test.set_id(1234); 我发送Varint32 coded_output-> WriteVarint32(test.ByteSize()); C#应用程序应该正好收到这些字节(以十六进制表示)03 08 d2 09. 03是其余部分是消息的大小。目前,我很难将从C#发回的响应发送给C++。我相信我会尽快完成。 – 2011-06-05 11:35:01

1

基本上它将取决于您使用的网络库以及它们两端的兼容性。在最低级别,数据以流或字节块的形式传输。当这些字节被转换回字节以上的任何更复杂的结构(甚至是int)时,编码显然很重要,并且需要在两端进行匹配。

最简单的事情就是试试看。

这听起来像你可能有兴趣尽可能紧凑地包装数据(从你的转换整数到字符的评论),在这种情况下,你可能应该只是在两端写一套低级包装例程。这样你就不用担心编码问题了,你可以从数据包中榨取最后一点。

1

varint编码没有endianess问题,它始终是小端设计。它以最低有效位7位开始一次存储7位数值,并且当没有剩余1位时使用第8位作为停止位。

在C#中使用Read7BitEncodedInt方法读取varint编码的整数。

+0

我不确定,但似乎Read7BitEncodedInt在我使用的MonoDevelop中不可用。任何其他想法? – 2011-06-04 10:44:51

+0

@ lord-didger:它在'BinaryReader'类中。如果您使用其他方式来读取数据,您可以轻松地调整代码,这只是几行代码。你可以在这里找到源代码:http://www.koders.com/csharp/fid4083672E4B426989ECED8C0C517B0327B94BC1CB.aspx – Guffa 2011-06-04 12:07:56