您的位置:首页 > 编程语言 > PHP开发

分析php获取客户端ip

2013-07-22 19:08 211 查看
用php能获取客户端ip,这个大家都知道,代码如下:

/**
* 获取客户端ip
* @param number $type
* @return string
*/
function getClientIp($type = 0) {
$type       =  $type ? 1 : 0;
static $ip  =   NULL;
if ($ip !== NULL) return $ip[$type];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos    =   array_search('unknown',$arr);
if(false !== $pos) unset($arr[$pos]);
$ip     =   trim($arr[0]);
}elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip     =   $_SERVER['HTTP_CLIENT_IP'];
}elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip     =   $_SERVER['REMOTE_ADDR'];
}
// IP地址合法验证
$long = sprintf("%u",ip2long($ip));
$ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
return $ip[$type];
}


虽然这个非常非常的简单,但是php本就是服务器端语言,为什么它能够获取客户端ip.这其实是一件神奇的事,至少我和我的小伙伴们惊呆了.

无论什么语言,服务器端按照理论来说,都应该获取不到客户端ip,无论是c++,erlang,或者其他.

有人可能认为c++不是可以获取客户端ip吗?

是的,的确可以,但是那个是c++写的客户端程序才可以,如果c++写的服务器端程序,还可以吗?

群里有人说:这个ip的获取是由于包发送的时候,同时带有ip,mac地址,所以自然就知道了.

我不这样认为,因为理论上来说,包发送的时候的确带上了ip地址,也带上了mac地址,但是从数据包的角度来解释的话,一般都是在局域网内部传输时才会包上MAC头,经过路由不断转发,实际上每经过一级设备都被剥去一层,到最后就只剩下TCP/IP的数据头和数据了。MAC只可能是在网络底层的物理层中传输。(也就是说client的mac地址信息是不可能在公网上传输的,公网上的MAC信息是最后一跳设备的接口MAC

http是应用层协议,因此,到应用层的时候都是数据,根本就不可能还包含ip地址,mac地址...

之后分析$_SERVER变量,这个变量里包含了很多客户端和服务器的一些信息.并且包括使用的web服务器,之后查询资料得出:

php能获取客户端ip地址的原因是,$_SERVER变量是从服务器那边获取的,也就是说:

真正获取客户端ip的是web服务器,比如:apache,nginx.

然后在由web服务器把$_SERVER变量传递给php.

本着分析到底的心态,我进行一次实验,抓包软件进行捕捉

捕捉如下:



很容易看得出,这里是底层的包,抓出来的ip地址也不在应用层,因此,这部分的ip,mac到应用层就已经没了

但是下一个包如下:



这个包是数据包,到了应用层仍然是在的,这里可以看出数据包中带有host然后传递给了web服务器,之后在由web服务器传递给php

其他小伙伴是否还有真相?欢迎拍砖
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: