欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA如何获取客户端IP地址和MAC地址

程序员文章站 2024-02-20 21:28:40
本文介绍了java如何获取客户端ip地址和mac地址 ,分享给大家,具体如下: 1.获取客户端ip地址 public string getip(httpse...

本文介绍了java如何获取客户端ip地址和mac地址 ,分享给大家,具体如下:

1.获取客户端ip地址

public string getip(httpservletrequest request) throws exception {
  string ip = request.getheader("x-forwarded-for");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      int index = ip.indexof(",");
      if (index != -1) {
        return ip.substring(0, index);
      } else {
        return ip;
      }
    }
  }
  ip = request.getheader("x-real-ip");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      return ip;
    }
  }
  return request.getremoteaddr();
}

为什么不直接使用request.getremoteaddr();而要在之前判断两个请求头"x-forwarded-for"和"x-real-ip"

x-forwarded-for: client1, proxy1, proxy2, proxy3

其中的值通过一个 逗号+空格 把多个ip地址区分开, 最左边(client1)是最原始客户端的ip地址, 代理服务器每成功收到一个请求,就把请求来源ip地址添加到右边。

所有我们只取第一个ip地址

x-real-ip,一般只记录真实发出请求的客户端ip

解决用localhost访问ip为0:0:0:0:0:0:0:1的问题

public string getip(httpservletrequest request) throws exception {
  string ip = request.getheader("x-forwarded-for");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      int index = ip.indexof(",");
      if (index != -1) {
        return ip.substring(0, index);
      } else {
        return ip;
      }
    }
  }
  ip = request.getheader("x-real-ip");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      return ip;
    }
  }
  ip = request.getheader("proxy-client-ip");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      return ip;
    }
  }
  ip = request.getheader("wl-proxy-client-ip");
  if (ip != null) {
    if (!ip.isempty() && !"unknown".equalsignorecase(ip)) {
      return ip;
    }
  }
  ip = request.getremoteaddr();
  return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
}

2.获取客户端mac地址

udpgetclientmacaddr umac = new udpgetclientmacaddr(sip);
string smac = umac.getremotemacaddr();

添加一个获取mac的时间限制

final udpgetclientmacaddr umac = new udpgetclientmacaddr(sip);
//---长时间获取不到mac地址则放弃
executorservice exec = executors.newfixedthreadpool(1);
callable<string> call = new callable<string>() {
  public string call() throws exception {
    return umac.getremotemacaddr();
  }
};
try {
  future<string> future = exec.submit(call);
  string smac = future.get(1000 * 1, timeunit.milliseconds);
  loginmonitor.setmacaddress(smac);
} catch (timeoutexception ex) {
  loginmonitor.setmacaddress("获取失败");
  logger.info("获取mac地址超时");
  ex.printstacktrace();
}
// 关闭线程池 
exec.shutdown();
//---

需要先获取ip地址作为参数构造一个udpgetclientmacaddr

udpgetclientmacaddr.java

package shmc.commonsys.security.controller;

import java.io.ioexception;
import java.net.datagrampacket;
import java.net.datagramsocket;
import java.net.inetaddress;
 
/** 
 * 主机a向主机b发送“udp-netbios-ns”询问包,即向主机b的137端口,发query包来询问主机b的netbios names信息。 
 * 其次,主机b接收到“udp-netbios-ns”询问包,假设主机b正确安装了netbios服务........... 而且137端口开放,则主机b会向主机a发送一个“udp-netbios-ns”应答包,即发answer包给主机a。 
 * 并利用udp(netbios name service)来快速获取远程主机mac地址的方法 
 * 
 */ 
public class udpgetclientmacaddr { 
  private string sremoteaddr; 
  private int iremoteport=137; 
  private byte[] buffer = new byte[1024]; 
  private datagramsocket ds=null; 
 
  public udpgetclientmacaddr(string straddr) throws exception{ 
    sremoteaddr = straddr; 
    ds = new datagramsocket(); 
  } 
 
  public final datagrampacket send(final byte[] bytes) throws ioexception { 
    datagrampacket dp = new datagrampacket(bytes,bytes.length,inetaddress.getbyname(sremoteaddr),iremoteport); 
    ds.send(dp); 
    return dp; 
  } 
 
  public final datagrampacket receive() throws exception { 
    datagrampacket dp = new datagrampacket(buffer,buffer.length); 
    ds.receive(dp); 
    return dp; 
  } 
  public byte[] getquerycmd() throws exception { 
    byte[] t_ns = new byte[50]; 
    t_ns[0] = 0x00; 
    t_ns[1] = 0x00; 
    t_ns[2] = 0x00; 
    t_ns[3] = 0x10; 
    t_ns[4] = 0x00; 
    t_ns[5] = 0x01; 
    t_ns[6] = 0x00; 
    t_ns[7] = 0x00; 
    t_ns[8] = 0x00; 
    t_ns[9] = 0x00; 
    t_ns[10] = 0x00; 
    t_ns[11] = 0x00; 
    t_ns[12] = 0x20; 
    t_ns[13] = 0x43; 
    t_ns[14] = 0x4b; 
 
    for(int i = 15; i < 45; i++){ 
      t_ns[i] = 0x41; 
    } 
    t_ns[45] = 0x00; 
    t_ns[46] = 0x00; 
    t_ns[47] = 0x21; 
    t_ns[48] = 0x00; 
    t_ns[49] = 0x01; 
    return t_ns; 
  } 
  public final string getmacaddr(byte[] brevdata) throws exception { 
    // 获取计算机名 
    int i = brevdata[56] * 18 + 56; 
    string saddr=""; 
    stringbuffer sb = new stringbuffer(17); 
    // 先从第56字节位置,读出number of names(netbios名字的个数,其中每个netbios names info部分占18个字节) 
    // 然后可计算出“unit id”字段的位置=56+number of names×18,最后从该位置起连续读取6个字节,就是目的主机的mac地址。 
    for(int j = 1; j < 7;j++) 
    { 
      saddr = integer.tohexstring(0xff & brevdata[i+j]); 
      if(saddr.length() < 2) 
      { 
        sb.append(0); 
      } 
      sb.append(saddr.touppercase()); 
      if(j < 6) sb.append(':'); 
    } 
    return sb.tostring(); 
  } 
 
  public final void close() throws exception { 
    ds.close(); 
  } 
 
  public final string getremotemacaddr() throws exception { 
    byte[] bqcmd = getquerycmd(); 
    send(bqcmd); 
    datagrampacket dp = receive(); 
    string smac = getmacaddr(dp.getdata()); 
    close(); 
 
    return smac; 
  } 
   
  public static void main(string args[]) throws exception{ 
    udpgetclientmacaddr umac=new udpgetclientmacaddr("172.19.1.198"); 
    umac=new udpgetclientmacaddr("192.168.16.83"); 
    system.out.println(umac.getremotemacaddr()); 
  } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。