分析php获取客户端ip

用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

其他小伙伴是否还有真相?欢迎拍砖

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值