Returning an IPv4 Address in an IPv6-Enabled Environment

rel="alternate" type="application/rss+xml" title="4GuysFromRolla.com Headlines" href="http://aspnet.4guysfromrolla.com/rss/rss.aspx" /> rel="stylesheet" href="http://aspnet.4guysfromrolla.com/css/text_aspnet.css" type="text/css" />

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 并存的将来是一个两全其美的办法。

Happy Programming!

 
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 这个错误提示是指在一个返回非 void 类型的函数中没有包含 return 语句。在函数执行完毕后,应该返回一个与函数声明中指定的类型相匹配的值,否则会出现编译错误。要解决这个问题,需要在函数中添加一个 return 语句,以返回正确的值。 ### 回答2: 这个错误通常出现在函数中没有包含return语句但返回值是非空的情况下。这个问题可能导致程序无法正常工作或者崩溃。 对于一个声明有返回类型而函数体中没有包含return语句的函数,编译器会认为函数执行完成后不会有返回值。但是,如果调用该函数时确实需要返回值,那么程序就会出现问题。 解决此问题的方法很简单,只需要在函数的所有可能的代码路径上都添加return语句即可。当然,在代码的逻辑上也需要确保函数的所有执行路径上都有返回值。 例如,以下代码段声明了一个返回整数的函数,但函数体中没有包含return语句: ``` int add(int a, int b) { int sum = a + b; printf("The sum is: %d\n", sum); } ``` 要解决这个问题,只需要在函数体的末尾添加一个return语句: ``` int add(int a, int b) { int sum = a + b; printf("The sum is: %d\n", sum); return sum; } ``` 如果函数中包含多个可能的返回值,那么就需要使用条件语句来确定哪个返回语句应该被执行。 总之,no return statement in function returning non-void这个错误的出现是因为函数的返回值类型已经指定,但在函数体中缺少必要的返回语句。确保函数的所有执行路径上都有正确的返回值,就可以解决这个问题。 ### 回答3: 在编程语言中,当定义一个非空函数时,我们需要在函数的最后使用return语句来返回函数值,以让计算机知道该函数的返回值是什么。然而,如果在一个非空函数中缺失了return语句,就会引发“no return statement in function returning non-void”(非空函数缺失return语句)的错误。 这个错误一般出现于当我们定义函数时,我们会在函数头部指明该函数的返回类型(即在函数名之前的类型,例如int、float等等),但我们在函数中却没有给出return语句。这会使得编译器在编译过程中找不到该函数的返回值,从而导致编译错误。 解决该错误的方法是,在函数末尾给出return语句,并在其中返回该函数应该返回的值。如果我们在函数中定义了多个返回点(例如if...else语句块),那么我们需要保证每一个返回点都有一个对应的return语句。 此外,当我们在函数定义时使用了void关键字来表示该函数没有返回值,那么即使我们没有在函数中使用return语句,也不会出现该错误,因为编译器知道该函数没有返回值。 总之,我们需要在定义函数时清楚地指明函数的返回类型,并在函数中正确地使用return语句来避免出现“no return statement in function returning non-void”错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值