为什么IPAddress.MapToIPv4()抛出ArgumentOutOfRangeException?

Pat*_*nga 13 .net ipv4 ipv6 bug-reporting base-class-library

此代码在最后一行抛出ArgumentOutOfRangeException

var initAddress = IPAddress.Parse("1.65.128.190");
var ipv6Address = initAddress.MapToIPv6();
Assert.IsTrue(ipv6Address.IsIPv4MappedToIPv6);
var ipv4Address = ipv6Address.MapToIPv4();
Run Code Online (Sandbox Code Playgroud)

谁能解释为什么MapToIPv6()和MapToIPv4()不兼容往返?

编辑:异常源自IP地址构造函数,由MapToIPv4()调用.

此外,当第一行是

var initAddress = IPAddress.Parse("1.65.128.90");
Run Code Online (Sandbox Code Playgroud)

没有例外被抛出

edit2:正如@Luaan转载的那样,我添加了标签[bug-reporting].还添加了[bcl].让我们看看是否有MS人员跟踪这些标签:)

edit3:在Connect https://connect.microsoft.com/VisualStudio/feedback/details/871964上报告

Lua*_*aan 18

好的,我实际已经验证了这一点,所以让我发布这个作为答案.

将IPAddress地址映射回IPv4时,类会出错.

根据.NET参考代码,它执行此操作:

long address = 
  (((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) |
  ((((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8)) << 16);
Run Code Online (Sandbox Code Playgroud)

任何在.NET中进行按位操作的人都应该明白这个问题 - 数字都是ints.因此,移动第二个ushort(m_Numbers[7])将给出负值,因为最重要的位是1.这意味着以高于字节结尾的所有IPv4地址127在从IPv6映射时都会导致错误.

简单的解决方法是:

long address = 
 (((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) 
 |
 (
  (uint)(((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8))
  << 16
 );
Run Code Online (Sandbox Code Playgroud)

只需在执行bitshift之前int将其转换为a uint就可以了.

当您考虑签名类型时,按位操作可能非常棘手.我想这些代码是从C++库中复制而来的,这个问题不会出现.

  • @ series0ne是的,它现在已被报道 - https://connect.microsoft.com/VisualStudio/feedback/details/871964/ipaddress-maptoipv4-throws-argumentoutofrangeexception (5认同)