CSDN博客

img panzi667

如何得到客户端的ip

发表于2004/10/14 9:59:00  5334人阅读

分类: java jsp

在JAVA里HttpServletRequest接口提供了getRemoteAddr()方法来获取客户端IP地址(其实是继承自ServletRequest接口的),使用很简单,方法如下:

假设已有HttpServletRequest对象request(Jsp中默认)

String ipaddress = request.getRemoteAddr();

但是这一方法有致命缺陷,就是不能穿透代理服务器。当系统架构中使用了代理服务器时,上述方法抓到的就是代理服务器的IP地址。在大中型J2EE架构的项目开发中,Java应用服务器常常需要使用集群与代理,故而上述方法便不可行了。笔者曾历查J2EE技术有关资料,未能发现可以一箭贯透代理服务器的直接可用的IP抓取方法。但J2EE是强大的,解决之道当然是不缺的,这里介绍一下我们的解决方法--使用带数字签名的Applet。

我们知道Applet是下载到客户端,在客户端的JVM上运行的,当Applet运行不涉及客户端的本地资源时使用Applet是个小Case(许多股票网站里动态显示交易曲线的技术就是这一招),但当要获取本地资源信息(即便只是抓个IP地址)时,就一定要对APPLET进行数字签名和认证(详情参见有关Java安全机制)。

带数字签名和认证的APPLET开发过程如下:

(1)开发APPLET的Java源程序并对其进行编译。

抓取本机(即客户机)IP的APPLET代码如下:
import java.applet.*;
import java.net.*;
import java.awt.*;

public class getipapp extends Applet
{
  public String myip()
  {

    String ipd="";
    try{
      //使用抓取本机Ip的方法getLocalHost(),返回一个InetAddress对象
      InetAddress addr=InetAddress.getLocalHost();

      //从InetAddress对象中取出数据放到byte类型的数组中
      byte[] ipAddr=addr.getAddress();
      int i=0;
      int ipget=0;
      //组装String类型的IP地址
      while(i<ipAddr.length){
       ipget=ipAddr[i];
        //对返回的数值进行转换整理
        if(ipget<0){ipget=256+ipget;}
        if(i==0){
        ipd=ipd+ipget;
        }else{
         ipd=ipd+"."+ipget;
        }
        i++;
      }
    }catch(UnknownHostException e){
    }
    return ipd;
  }

  public getipapp()
  {
  }

  //Initialize the applet
  public void start()
  {
  }
}

(2)用JAR工具对类文件和资源文件进行封装。

  当前目录下:
  jar cvf myip.jar *.class

(3)用keytool创建公钥和密钥,生成X。509V1签名证书,输出证书。

  当前目录下:
  keytool -genkey -keystore myip.keystore -alias myip

说明:keystore将用来存放密匙(private keys)和公共钥匙的认证,此命令生成了一个名为myip.keystore的keystore文件,接着这条命令,系统会接着有提示的要求填写若干内容,比如创建人、公司名称、地址、设定的密码等等,随便填写后完成。

(4)将公共钥匙导入到安全证书cer文件中。

当前目录下:
keytool -export -keystore myip.keystore -alias myip -file myip.cer

说明:此命令生成一个名为myip.cer的安全证书文件(这也是客户端运行访问本地资源的applet时需要的文件),使用命令当中会提示你输入密码,输入先前设定的密码即可。

至此,一个带数字签名和认证的APPLET开发完成。此APPLET运行时一旦通过客户端的许可验证(详情下述),便能抓取到客户机的IP地址,然后是将此地址传递到服务器上。我们在实践中使用javascript脚本直接与applet通讯,将抓取到的IP地址存放到页面元素中,然后通过表单将IP地址提交到服务器,方法如下。

(5)WEB(一般是登录页)获取applet参数的设置方法:

在<body>与</body>之间加入:
<applet code="getipapp.class" codebase = "" archive = "myip.jar"
  width="0" height="0" name="getipapp">
</applet>
和<input type="hidden" name="iptxt">(这是网页中用来存放applet参数的页面元素)

很重要:

在<head>与</head>之间加入:
<SCRIPT LANGUAGE=javascript>
function getmyip()
{
   //假设<input type="hidden" name="iptxt">元素在form1表单中
    window.document.form1.iptxt.value=window.document.getipapp.myip();
}
</ SCRIPT >

说明:利用javascript中将applet视为页面元素并提供简单通讯的方法直接从页面上取得applet获取的客户端IP地址,并通过表单提交给服务器(方法略)。

现在,客户端需要做的就是安装jre虚拟机(建议1.4.1以上版本),在Windows系统中成功安装后在控制面板中会看见一个"Java Plug-in"图标,打开该程序后在"浏览器"中确认将系统使用的浏览器钩上(IE或NetScape)。重启浏览器,访问服务器上装有applet的网页,此时会自动弹出安全证书的验证信息,当确认该证书可行后,带有该证书的applet就可以在你的机器上为所欲为了(呵呵,也没干什么,就打听了一下你机器上的IP地址),同时在"Java Plug-in"的"证书→带签名的小程序"中会自动导入你所签发的安全证书。

说了这么多,其实主要介绍了穿透代理服务器获取客户端IP的applet的一个完整方案。相信在J2EE架构下解决方法还很多,希望大家多多交流。(另外,这个方案中只获取了本机的主IP,若要取到本机的所有IP则在applet的源码中做些改动即可。)

阅读全文
0 0

相关文章推荐

img
取 消
img