今天查询数据库的表数据时发现有些保存的IP地址是 ::1,查看了一下原始代码是使用Request . ServerVariables [ "REMOTE_ADDR" ]获得的客户端IP地址,::1是使用IP v6 的地址格式表示的是回送地址,即本机地址(127.0.0.1)的 ipv6格式;
顺便找了一篇Ipv6的简单介绍:
IPv6是“Internet Protocol Version 6”的缩写,它是IETF设计的用于替代现行版本IP协议-IPv4-的下一代IP协议。
基于对效率、功能、灵活性和应用性等多个方面因素的综合考虑比较, IETF 决定在 IPv6 中采用 128 位固定长度的地址方案。
IPv6 地址的表示形式:
用文本方式表示的 IPv6 地址有三种规范的形式:
1. 优先选用的形式是 X:X:X:X:X:X:X:X ,其中 X 是 1 个 16 位地址段的十六进制值。例如:
FEDC:BA98:7654:4210:FEDC:BA98:7654:3210
2001:0:0:0:0:8:800: 201C : 417A
每一组数值前面的 0 可以省略。如 0008 写成 8
2. 在分配某种形式的 IPv6 地址时,会发生包含长串 0 位的地址。为了简化包含 0 位地址的书写,可以使用 “::” 符号简化多个 0 位的 16 位组。 “::” 符号在一个地址中只能出现一次。该符号也可以用来压缩地址中前部和尾部的 0 。举例如下:
FF01:0:0:0:0:0:0:101 多点传送地址
0:0:0:0:0:0:0:1 回送地址
0:0:0:0:0:0:0:0 未指定地址
可用下面的压缩形式表示:
FF01::101 多点传送地址
::1 回送地址
:: 未指定地址
3. 在涉及 IPv4 和 IPv6 节点混合的这样一个节点环境的时候,有时需要采用另一种表达方式,即 X:X:X:X:X:X:D.D.D.D ,其中 X 是地址中 1 个高阶 16 位段的十六进制值, D 是地址中低阶 8 位字段的十进制值(按照 IPv4 标准表示)。例如:下面两种嵌入 IPv4 地址的 IPv6 地址。
0:0:0:0:0:0:202.204.112.79 嵌入 IPv4 地址的 IPv6 地址
0:0:0:0:0:FFFF:202.201.112.10 嵌入 IPv4 地址的 IPv6 地址
写成压缩形式为:
::202.204.112.68
::FFFF.202.204.112.13
同时 IPv6 的地址按寻址方式和功能的不同,又可以分为 3 中基本类型。
1.单播地址( Unicast )
用来标识一个单接口。发送给一个单播地址的包传递到由该地址标识的接口上。
2. 任意点播地址( Anycast )
一般分配给属于不同节点的多个接口。发送给一个任意点播地址的包传送到该地址标识的、根据选路协议距离度量最近的一个接口上。
3. 组播地址( Multicast )
一般用来标识不同节点的一组接口,发送给一个组播地址的包传送到该地址所标识的所有接口上。
IPv6 中没有广播地址,它的功能正在被组播地址所代替。
在 IPv6 地址格式中,任何全“ 0 ”和“ 1 ”的字段都是合法值。特别是前缀可以包含“ 0 ”值字段或以“ 0 ”为终结。其中“ ::1 ”回返地址,具有一个目的地址为回返地址的包不应发送出单节点之外, IPv6 路由器也不会转发这样的包;“ :: (即全 0 )”为未指定地址。当移动节点返回家乡链路时,用这个未指定地址作为源地址来发送邻居请求获得家乡代理的链路层地址。
所有类型的 IPv6 地址都被分配到接口,而不是节点。一个 IPv6 单播地址属于单个接口,即属于单个节点。而具有多个接口的节点,则可以有多个单播地址,其中任何一个都可以用作该节点的标识符,至少有一个链路本地地址。
也有人使用
以下代码获得客户端IP地址
string szRemoteAddr = Request.ServerVariables["REMOTE_ADDR"]; string szXForwardedFor = Request.ServerVariables["X_FORWARDED_FOR"]; string szIP = "";
HTTP头X-Forwarded-For 欺骗,所以还是使用
if (Request.ServerVariables["HTTP_VIA"]==null) { szIP = szRemoteAddr; } else
{
szIP = szXForwardedFor; // 使用代理
if (szIP.IndexOf(",") > 0)
{
string [] arIPs = szIP.Split(','); // "," 真实地址和代理之间的分割
foreach (string item in arIPs)
{
if (!isIPAddresss(item))
{
return item;
}
}
}
}
return szIP;
但这个方法可以被伪造的Request .ServerVariables [ "REMOTE_ADDR" ]吧