是什么决定了IPv6地址由System.Net.IPAddress.ToString格式()? [英] What dictates the formatting of IPv6 addresses by System.Net.IPAddress.ToString()?

查看:183
本文介绍了是什么决定了IPv6地址由System.Net.IPAddress.ToString格式()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

内置的.NET方法System.Net.IPAddress.ToString()的行为不一致的IPv6地址。

由于字节数组 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ,在某些环境中AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA返回,而另一些返回AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:172.172.172.172。

据我所知,都是有效的IPv6格式,但我想应该能够解释的差异。

看来,新的环境(Windows 7和Server 2008 R2中)更有可能生产出第一台的行为,所以我检查了类似.NET Framework版本明显的差异,但我一直无法检测的模式。

有没有一种方法可以让我比其他选择一种格式,或者我必须解决这个code得到一致的行为?

code重现:

 字节[]字节= {和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA,和0xAA} ;
    ip地址MYIP =新的ip地址(字节);
    Console.WriteLine(myIP.ToString());
 

解决方案

在的ToString的内部闲逛,使用的反光,你可以看到,如果确定该操作系统支持IPv6(用于支持某些值),然后将其推迟到所谓的 WSAAddressToString ,而如果该标志没有设置,但它确实手动格式化(从它的内部字节数组)为:

  addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [0]}))附加('。 :');
addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [1]}))附加(':')。
addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [2]}))附加(':')。
addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [3]}))附加(':')。
addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [4]}))附加(':')。
addressString.Append(的String.Format(CultureInfo.InvariantCulture,{0:X4},新的对象[] {this.m_Numbers [5]}))附加(':')。
addressString.Append((int)的((this.m_Numbers [6]≥→8)及0xff的))。追加('。');
addressString.Append((int)的(this.m_Numbers [6]&安培; 0xff的))。追加('。');
addressString.Append((int)的((this.m_Numbers [7]≥→8)及0xff的))。追加('。');
addressString.Append((int)的(this.m_Numbers [7]&安培; 0xff的));
 

这将始终返回你出的第二格式。

无论是标志操作系统支持IPv6的标志设置似乎取决于这两个类中的内部知识(版本必须> 2000),它会出现一个实际尝试创建IPv6套接字 - 所以,如果你对一个XP机IPv6的残疾人,我想你也会得到这第二种格式。

The builtin .Net method System.Net.IPAddress.ToString() behaves inconsistently for IPv6 addresses.

Given the byte array 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA, in some environments "aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa" is returned, whereas others return "aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:172.172.172.172".

I understand that both are valid IPv6 formats, but I would like to be able to explain the difference.

It seems that newer environments (Windows 7 and Server 2008 R2) are more likely to produce the first behaviour, so I've checked obvious differences like .Net framework version, but I've been unable to detect a pattern.

Is there a way I can select one format over the other, or do I have to code around this to get consistent behaviour?

Code to recreate:

    byte[] bytes = {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
    IPAddress myIP = new IPAddress(bytes);
    Console.WriteLine(myIP.ToString());

解决方案

Poking around in the internals of ToString, using Reflector, you can see that if it's determined that the OS supports IPv6 (for some value of supports), then it defers to a Win32 function called WSAAddressToString, whereas if this flag isn't set, it does manual formatting (from it's internal byte array) as:

addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[0] })).Append(':');
addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[1] })).Append(':');
addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[2] })).Append(':');
addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[3] })).Append(':');
addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[4] })).Append(':');
addressString.Append(string.Format(CultureInfo.InvariantCulture, "{0:x4}", new object[] { this.m_Numbers[5] })).Append(':');
addressString.Append((int) ((this.m_Numbers[6] >> 8) & 0xff)).Append('.');
addressString.Append((int) (this.m_Numbers[6] & 0xff)).Append('.');
addressString.Append((int) ((this.m_Numbers[7] >> 8) & 0xff)).Append('.');
addressString.Append((int) (this.m_Numbers[7] & 0xff));

which will always return the second format you've shown.

Whether the flag "OS supports IPv6" flag is set seems to depend on both internal knowledge within the class (version must be > 2000) and it would appear an actual attempt to create an IPv6 socket - so if your on an XP machine with IPv6 disabled, I think you'll also get this second format.

这篇关于是什么决定了IPv6地址由System.Net.IPAddress.ToString格式()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆