最近想写个B/S架构的聊天系统,因为以前做过C/S架构的QQ聊天系统,所以对于Socket通信编程只是一个巩固。对于C/S架构的聊天系统,由于存在客户端Java应用,所以直接在代码中获取客户端的IP,应用的方法为:
String ip = InetAddress.getLocalHost().getHostAddress();
然而对于WEB系统来说,客户端只是一个浏览器,怎么才能获取用户的IP呢,而且又要分内网环境和外网环境两种。
内网环境:
聊天系统用于内网的话,我首先想到了通过JS来实现获取用户的IP,确实也有方法可以支持:
//通过js获得客户端IP,这里获取的IP是本机所有的IP(包括内网和外网)
function GetLocalIPAddr(){
var oSetting = null;
var ip = null;
try{
oSetting = new ActiveXObject("rcbdyctl.Setting");
ip = oSetting.GetIPAddress;
if (ip.length == 0){
return "没有连接到Internet";
}
oSetting = null;
}catch(e){
return ip;
}
return ip;
}
不过此方法只支持IE浏览器,我不得不加了个判断浏览器类别的方法:
//首先判断客户端的浏览器情况
$(function(){
if($.browser.msie){
clientIP = GetLocalIPAddr();
$("#showMessage").html("您的IP为:"+dealWith(clientIP));
sendMessageToServlet("busi=connect&connectIP="+dealWith(clientIP));
}else if($.browser.opera){
//alert("这是一个opera浏览器!");
$("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!");
}else if($.browser.mozilla){
//alert("这是一个mozilla浏览器!");
$("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!");
}else if($.browser.safa){
//alert("这是一个safa浏览器!");
$("#showMessage").html("建议您使用IE浏览器,否则要手动输入IP!");
}
});
怎么才能完整的获取客户端的IP呢?(如果有哪位朋友做过,期望指点一下啊,交个朋友,呵呵)
外网环境:
我们这边在做的网上营业厅系统中有获取用户外网IP的方法,实现方法:
public static String getCurrentIP(HttpServletRequest request){
String result = "";
if (result == null || result.length() == 0
|| "unknown".equalsIgnoreCase(result)) {
result = request.getHeader("x-forwarded-for");
}
if (result == null || result.length() == 0
|| "unknown".equalsIgnoreCase(result)) {
result = request.getHeader("X-Forwarded-For");
}
if (result == null || result.length() == 0
|| "unknown".equalsIgnoreCase(result)) {
result = request.getHeader("Proxy-Client-IP");
}
if (result == null || result.length() == 0
|| "unknown".equalsIgnoreCase(result)) {
result = request.getHeader("WL-Proxy-Client-IP");
}
if (result == null || result.length() == 0
|| "unknown".equalsIgnoreCase(result)) {
result = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (!StringUtils.isEmpty(result)) {
if (result.indexOf(".") != -1){ // 没有"."肯定是非IPv4格式
Pattern pat = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
Matcher mat = pat.matcher(result);
result = null;
while (mat.find()) {
result = mat.group(0);
break;
}
}
else
result = null;
}
下面是网上广为流传的解释:
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。
如果使用了反向代理软件,将http://192.168.1.110 :2046/ 的URL反向代理为 http://www.xxx.cn / 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器 无法直接拿到客户端的IP,服务器 端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问http://www.5555.cn /index.jsp/ 时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110 :2046/index.jsp ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过 request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。
public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
可是当我访问http://www.5555.cn /index.jsp/ 时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问http://192.168.1.110 :2046/index.jsp 时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off 则:X-Forwarded-For: unknown
于是可得出获得客户端真实IP地址的方法二:
public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
public String getIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?
答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110
分享到:
相关推荐
在很多应用下都可能有需要将用户的真实IP记录下来,这时就要获得用户的真实IP地址,在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等...
在C#编程中,文件上传和下载是常见的任务,尤其在客户端/服务器(C/S)和浏览器/服务器(B/S)架构中。本篇将详细解释如何使用C#实现这两种场景下的文件上传和下载功能。 首先,对于C/S模式,我们通常会创建一个...
在.NET框架中,获取客户端MAC(Media Access Control)地址是一项常见的网络编程任务,尤其是在服务器端需要识别或验证连接设备时。MAC地址是物理网络接口控制器(NIC)的唯一标识符,用于在网络通信中区分不同的...
B/S架构(Browser/Server)是一种客户端-服务器模式,其中客户端通常是网络浏览器,而服务器端则负责处理请求并返回数据。在这种架构下,Java后端作为服务器端,处理与摄像头交互的逻辑,然后通过HTTP协议将预览画面...
在开发B/S架构的应用程序时,为了确保用户的身份验证准确性以及追踪管理的需求,开发者常常需要获取客户端计算机的MAC地址和IP地址等信息。传统的做法是在服务器端通过各种技术手段(如调用Win32API、执行`nbtstat`...
B/S(Browser/Server)在线考试系统是一种基于Web技术的考试管理系统,它利用浏览器作为客户端,服务器端处理所有业务逻辑和数据存储。这样的设计模式使得用户无需安装特定软件,只需通过浏览器就能进行考试、阅卷、...
前端设备负责图像采集,通过网络将视频流传输到中心管理平台,平台处理并存储视频,用户通过C/S或B/S客户端进行访问。 2.2 方案具体实现说明: 前端设备通常选用红外防水枪形摄像机,具有夜间监控能力和防雨雪功能...
本次作业主要针对TCP/IP协议栈中的ECHO协议客户端及服务器程序设计,并加入了主机名或IP地址解析功能,旨在加深学生对TCP/IP协议的理解和应用能力。具体目标包括: 1. **ECHO协议客户端程序设计**:设计并实现一个...
在做B/S结构的系统时,我们常常需要获取客户端的一些信息,如IP和MAC,以结合身份验证。要获取服务器端的MAC很容易,但是要获取客户端的MAC的地址确要花费一翻心思,通常的做法是调用Win32API或直接调用nbtstat命令...
这种结构让需要频繁操作数据库的用户使用C/S客户端,确保安全性和效率,而管理层则使用B/S客户端进行查询,享受其灵活性和便捷性。这种结合方式可以最大化利用两种架构的优点,减少各自的缺点。 在公交系统数据采集...
这些信息在某些应用场景下非常有用,比如在B/S(浏览器/服务器)架构的系统中进行身份验证或定制化服务。 1. **获取MAC地址**: - MAC地址(Media Access Control Address)是物理网络接口的唯一标识符。在...
开发者可能会通过编写恶意代码,使得攻击者能够绕过正常的安全机制,直接获取服务器资源或控制客户端行为。这些后门可能在Web服务、数据库连接、用户认证等方面存在。 VC++(Visual C++)和MFC(Microsoft ...
<=\bMAC Address=\s)[0-9A-Fa-f]{2}(-[0-9A-Fa-f]{2}){5}", RegexOptions.IgnoreCase); Match match = regex.Match(result); if (match.Success) { return match.Value.Replace("-", ":"); //返回匹配到的MAC...
B/S架构是一种分布式系统架构,它将系统的功能分为两部分:客户端(浏览器)和服务器端。客户端仅需一个通用浏览器,无需安装其他软件,即可通过网络与服务器端进行交互。这种架构为系统的部署和维护提供了极大的...
第一部分 TCP/IP基础 第1章 开放式通信模型简介 1 1.1 开放式网络的发展 1 1.1.1 通信处理层次化 2 1.1.2 OSI参考模型 3 1.1.3 模型的使用 5 1.2 TCP/IP参考模型 7 1.3 小结 7 第2章 TCP/IP和Internet 8 2.1 一段...
在B/S模式中,客户端的浏览器通过URL访问Web服务器。当接收到请求后,Web服务器会进一步向数据库服务器请求数据。数据获取后,Web服务器将结果以HTML格式返回给客户端浏览器。整个过程简单高效,用户无需在本地安装...
《基于B/S模式的嵌入式视频监控系统的设计》 嵌入式视频监控系统作为一种现代化的监控手段,近年来在各个领域得到了广泛应用。本文探讨了一种基于B/S模式的嵌入式视频监控系统的设计,该系统以强大的ARM9处理器S3C...
其中,方案二和方案三的效果较为相似,适用于B/S架构系统在客户端内置IE浏览器或操作系统自带IE浏览器中打开的情况,适用于少量信息交互的场景,且可能需要定制开发。 ##### 3. 讯鸟客户端与业务系统统一登录方案 ...
26.2.2 使用FTP客户端建立连接 288 26.2.3 FTP安全 296 26.2.4 FTP服务器及守护进程 299 26.2.5 匿名FTP访问 299 26.3 使用TFTP 300 26.3.1 FTP与TFTP的区别 301 26.3.2 TFTP命令 301 26.4 小结 301 第27章 使用...