我正在修补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()
然而。
花了一些时间才发现,但我发现了什么 - 如果有的话?这是为什么?
答案 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()。不用担心溢出。