当前位置: 移动技术网 > IT编程>开发语言>Java > JAVA如何获取客户端IP地址和MAC地址

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

本文介绍了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()); 
  } 
} 

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网