ReadInt32与ReadUInt32

时间:2014-06-07 15:31:28

标签: c# binaryreader uint32

我正在修补IP数据包'解析器'当我发现奇怪的事情时。

在解析IP地址时,在C#

private uint srcAddress; 
// stuff
srcAddress = (uint)(binaryReader.ReadInt32());

诀窍,所以你认为这个VB.Net等效

Private srcAddress As UInteger
'' stuff
srcAddress = CUInt(binaryReader.ReadInt32())

也可以做到这一点。它没有。这个:

srcAddress = reader.ReadUInt32()

然而。

花了一些时间才发现,但我发现了什么 - 如果有的话?这是为什么?

1 个答案:

答案 0 :(得分:5)

默认情况下,VB.NET执行C#默认不执行的操作。它总是检查数值溢出。并且在您的代码中触发,最后一位为1而不是0的IP地址将产生一个负数,并且无法转换为UInteger。一种只能存储正32位数的数据类型。

C#也有此选项,您必须在代码中明确使用 checked 关键字。或者使用默认情况下VB.NET项目打开的相同选项:Project + Properties,Build选项卡,Advanced,勾选“Check for arithmetic overflow / underflow”复选框。 VB.NET项目中的相同选项被命名为“删除整数溢出检查”,默认为关闭。

请注意这些默认值如何影响语言的语法。在C#中,你来编写一个转换来将值转换为不兼容的值类型。在VB.NET中没有必要,运行时检查可以帮助您摆脱困境。有不好的麻烦,溢出会产生极大的不良后果。在你的情况下,不会发生这种情况,IP地址确实是无符号数。

请记住关于IP地址的另一个怪癖,套接字最初是在由LSD和大端处理器驱动的Unix机器上发明的。您通常必须使用IPAddress.NetworkToHostOrder()以正确的顺序获取地址。其中只有带有符号整数类型作为参数的重载。所以使用ReadInt32()实际上是正确的,假设它是一个IPv4地址,你将它直接传递给NetworkToHostOrder()。不用担心溢出。