Returning an IPv4 Address in an IPv6-Enabled Environment

Introduction
The Internet is best described as a "network of networks," and every device which is connected to the Internet is uniquely identified by its Internet Protocol (IP) address. When client browsers connect to websites, they pass along a collection of information which the website can use for various purposes - these are known as the Request Headers, and the IP address of the client machine is included in this information. Although a machine's IP address is not guaranteed to be 100% accurate, many web developers capture it for logging and other purposes.

介绍
互联网的最佳描述是“网络之网”,每一个连接进来的设备都有一个唯一的标示:互联网规约地址(IP地址)。当客户浏览器连接到网站时,会被收集一些信息用于各种目的 -- 例如请求报头,客户机的IP地址这些信息。尽管不能保证 100% 正确的取得IP地址的信息,但仍有很多开发者用来记录用户登录事件或其他目的。

One challenge in capturing IP addresses is that there are differences in the IP address format between IP version 4 and IP version 6. When the IPv4 protocol is the only protocol enabled on the web server, accessing the IP address in the Request Headers will return the familiar IPv4 address. However, if IPv6 is also enabled, it will take precedence over IPv4. While earlier versions of Windows supported IPv6, Windows Vista is the first to have it enabled by default. Therefore, if you are using Windows Vista as the operating system for your development machine or web server, you may have noticed that the client IP addresses retrieved from the Request Headers are being returned in the IPv4 format.

在 IPv4 和 IPv6 之间的差异是获取 IP 地址的一个难题。如果网站服务器仅安装了 IPv4 协议,那么我们将只能捕获 IPv4 的地址。然后,如果 IPv6 协议一旦被安装,则会优先于 IPv4。虽然早期的 Windows 版本也支持 IPv6,但 Windows Vista 是第一个默认安装的。因此,在你使用 Windows Vista 作为开发机或网站服务器的操作系统时,可能发现客户端的返回的数据都是 IPv4 格式的(注:事实上,在测试过程中,我发现返回的地址都是 IPv6格式的,不知道是原文写错还是我翻译的有问题)

In this article we will examine a short bit of code that will seamlessly convert the IPv6 address returned by Windows Vista (or other IPv6-enabled environments) into an IPv4 format. This is useful if your database or back-end logic is expecting an IPv4 address. Read on to learn more!

在本文中,我们将尝试使用一小段代码来实现在Windwos Vista (或其他 IPv6 环境)下将 IPv6 无缝转换成 IPv4。如果你的数据库或后台操作期望得到 IPv4 地址,那么本文将对你很有帮助。

An IP Overview
In the early 1980s, version 4 (IPv4) of the Internet Protocol was introduced, and this version is still in use on the vast majority of networks around the world. IPv4 addresses are in the format xxx.xxx.xxx.xxx, e.g. 192.168.1.1. Each of the four elements of an IPv4 address is comprised of a single byte of data, which means that the largest possible IPv4 address is 255.255.255.255. This gives a maximum number of unique IPv4 addresses at just over 4 billion, though approximately 18 million of these are reserved for private networks.

IP概述
在二十世纪八十年代初期,第四版的互联网协议(IPv4)引入以来,至今仍在世界范围内被广泛的、大量的应用。IPv4 地址的格式是 xxx.xxx.xxx.xxx,例如 192.168.1.1。四段中每一段都是一个单字节的数据,这意味着最大的 IPv4 地址是 255.255.255.255。这样就有了 40 多亿个独立的 IPv4 地址,但大约有一千八百多万个地址被保留给了私有网络。

Although processes such as Network Address Translation (NAT) have helped expand the potential pool of IP addresses, with more computers, cell phones, and Internet-connect devices, the limits imposed by IPv4 are beginning to be reached. Therefore, version 6 of Internet Protocol was devised in the mid 1990s. Unlike the 32-bit IPv4 addresses, IPv6 addresses are 128-bit in the format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx, where each x is a 4-bit hexidecimal digit. This expanded format gives a theoretical maximum number of unique IPv6 addresses of 2128 - this is thought highly unlikely ever to run out.

尽管网址解析(NAT)可以帮助扩展更多的地址来连接计算机、电话和其他互联网设备,但 IPv4 的局限型已经开始达成了共识,因此,在二十世纪九十年代设计出了第六版互联网协议(IPv6)。不同于 32 位的 IPv4 地址,IPv6 地址是 128 位的,它的格式是 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx,每一个 x 表示一个十六进制的数字。这样,从理论上来说,就可以提供 2 的 128 次方个独立的 IPv6 地址,几乎不可能再使用完了。

A common method used by ASP.NET developers for retrieving a visitor's IP address from the Request Headers is to use the UserHostAddress property of the HttpRequest object like so:

ASP.NET 开发人员获取访问者的 IP 地址有个通用的方法,象这样使用 HttpRequest 对象的 UserHostAddress 属性:

' VB
Dim ClientIP As String = Request.UserHostAddress


// C#
string ClientIP = Request.UserHostAddress;

When the IPv4 protocol is the only protocol enabled, this will return a familiar IPv4 address. However, if IPv6 is also enabled, it will take precedence over IPv4, and the above code will return an IPv6 address instead. Since the release of the Vista Update patch for Visual Studio.NET 2005 SP1, many ASP.NET developers have started to use Vista as their development platform. Although Microsoft shipped the IPv6 protocol with previous versions of Windows, Vista is the first version where IPv6 is enabled by default. This, of course, means that Request.UserHostAddress no longer works as expected because it is suddenly returning an IPv6 address.

当只有 IPv4 协议时,我们将获取一个熟悉的 IPv4 地址,但如果 IPv6 协议也被安装了,那么将优先于 IPv4,返回一个 IPv6 的地址。自从微软公司发布了 Vista 版本的 VS 2005 SP1 的更新补丁后,越来越多的开发人员将 Vista 作为了他们的开发平台。而尽管以前的 Windows 版本中也已经捆绑了 IPv6,但 Vista 却是第一个默认安装的,这就意味着 Request.UserHostAddress 返回的数据不再是我们期望的那样,因为它返回了一个 IPv6 的地址。

Solution
Although IPv6 can be disabled in Vista, there is thankfully no need to do this, as it is very easy to return an IPv4 address even when IPv6 is enabled. Firstly, add the following code to your ASP.NET project:

解决方案
尽管在 Vista 中我们可以禁用 IPv6,但所幸我们不必这么做,我们有更简单的办法在 IPv6 环境中来获取 IPv4 的地址。首先我们将以下代码添加到你的项目中:

Visual Basic Code:

Imports System
Imports System.Net

Public Class IPNetworking
  Public Shared Function GetIP4Address() As String
    Dim IP4Address As String = String.Empty

    For Each IPA As IPAddress In Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress)
      If IPA.AddressFamily.ToString() = "InterNetwork" Then
        IP4Address = IPA.ToString()
        Exit For
      End If
    Next

    If IP4Address <> String.Empty Then
      Return IP4Address
    End If

    For Each IPA As IPAddress In Dns.GetHostAddresses(Dns.GetHostName())
      If IPA.AddressFamily.ToString() = "InterNetwork" Then
        IP4Address = IPA.ToString()
        Exit For
      End If
    Next

    Return IP4Address
  End Function
End Class

C# Code:

using System;
using System.Net;

public class IPNetworking
{
  public static string GetIP4Address()
  {
    string IP4Address = String.Empty;

    foreach (IPAddress IPA in Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress))
    {
      if (IPA.AddressFamily.ToString() == "InterNetwork")
      {
        IP4Address = IPA.ToString();
        break;
      }
    }

    if (IP4Address != String.Empty)
    {
      return IP4Address;
    }

    foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
    {
      if (IPA.AddressFamily.ToString() == "InterNetwork")
      {
        IP4Address = IPA.ToString();
        break;
      }
    }

    return IP4Address;
  }
}

Then use the following code every time you need an IPv4 address:

然后,在你需要获取 IPv4 地址的地方使用以下的代码:

' VB
Dim ClientIP As String = IP4.GetIP4Address


// C#
string ClientIP = IP4.GetIP4Address();

Conclusion
In this article we saw how to program ASP.NET to return an IPv4 address in an IPv6-enabled environment. As the IPv4 protocol is likely to co-exist with the IPv6 protocol for the foreseeable future, this gives web programmers the best of both worlds.

总结
在本文中,我们看到了如何使用 ASP.NET 在 IPv6 的环境中获取一个 IPv4 地址,这在 IPv4 与 IPv6 并存的将来是一个两全其美的办法。

你可能感兴趣的:(Environment)