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());
}
}

JAVA获取客户端IP地址和MAC地址的更多相关文章

  1. JAVA获取客户端IP地址

    在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...

  2. java获取客户端ip地址工具类

    public class IpUtils { private static final String[] HEADERS = { "X-Forwarded-For", " ...

  3. Java 获取客户端ip返回127.0.0.1问题

    Java开发中使用 request.getRemoteAddr 获取客户端 ip ,返回结果始终为127.0.0.1.原因是服务器使用了nginx反向代理. 解决办法:在nginx配置文件nginx. ...

  4. Java获取客户端IP

    在开发工作中,我们常常需要获取客户端的IP.一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...

  5. Java 获取客户端IP

    像移动网关一样,iisforward这个ISAPI过滤器也会对request对象进行再包装,附加一些WLS要用的头信息.这种情况下,直接用request.getRemoteAddr()是无法取到真正的 ...

  6. Nginx反向代理后,java获取客户端真实IP地址

    一般情况下,java获取客户端IP地址的方法为request.getRemoteAddr();但这只是在没有网关或者代理的情况下,如果客户端将请求发送到nginx,再由nginx进行反向代理到目标服务 ...

  7. java获取服务器IP地址及MAC地址的方法

    这篇文章主要介绍了java编程实现获取机器IP地址及MAC地址的方法,实例分析了Java分别针对单网卡及多网卡的情况下获取服务器IP地址与MAC地址的相关技巧,需要的朋友可以参考下   本文实例讲述了 ...

  8. JS获取客户端IP地址、MAC和主机名七种方法

    一.使用JS获取客户端IP的几个方法方法一(只针对IE且客户端的IE允许AcitiveX运行,通过平台:XP,SERVER03,2000).获取客户端IP代码:<HTML><HEAD ...

  9. JAVA获取客户端请求的当前网络ip地址(附:Nginx反向代理后获取客户端请求的真实IP)

    1. JAVA获取客户端请求的当前网络ip地址: /** * 获取客户端请求的当前网络ip * @param request * @return */ public static String get ...

随机推荐

  1. 单源最短路径(1):Dijkstra 算法

    一:背景 Dijkstra 算法(中文名:迪杰斯特拉算法)是由荷兰计算机科学家 Edsger Wybe Dijkstra 提出.该算法常用于路由算法或者作为其他图算法的一个子模块.举例来说,如果图中的 ...

  2. python 将文件夹内的图片转换成PDF

    import os import stringfrom PIL import Imagefrom reportlab.lib.pagesizes import A4, landscapefrom re ...

  3. Windows zip安装MySQL

    1. mysqld初始化时my.ini的第二个默认位置是%windir%/my.ini rem 1.查看此变量对应的目录,在此目录下编辑 my.ini,mysqld会自动找到 echo %WINDIR ...

  4. python 小脚本升级-- 钉钉群聊天机器人

    一则小脚本(工作中用) 在这篇文章中写的监控的脚本,发送监控的时候 是利用的邮箱,其实在实际,邮箱查收有着不方便性,于是乎升级, 我们工作中,经常用钉钉,那么如果要是能用到钉钉多好,这样我们的监控成功 ...

  5. Ajax 的用法

    1.什么是 Ajax? Ajax,英文名 Asynchronous JavaScript and XML,也就是异步的 JavaScript 和 XML.它不是一门新的语言,而是一种使用现有标准的新方 ...

  6. requireJS对文件合并与压缩(二)

    requireJS对文件合并与压缩 RequireJS提供了一个打包与压缩工具r.js,r.js的压缩工具使用UglifyJS进行压缩的或Closure Compiler.r.js下载 require ...

  7. c#代码技巧

    1.#region #endregion 1.#region 是一个分块预处理命令,主要用于编辑代码分段,在编译时会自动屏蔽,同时该指令可以使代码在VS代码编辑器中折叠或展开: 2.#region必须 ...

  8. 读书笔记:《HTML5开发手册》-- 现存元素的变化

    继续学习HTML5语义化的内容,今天主要介绍一下,HTML5之前的元素经HTML5规范后的语义及一些使用示例. 一.cite HTML5对cite元素的定义进行了很大的修改,在HTML4中,cite元 ...

  9. Life In Changsha College- 第二次冲刺

    第二次冲刺任务 设计留言板功能. 用户故事 用户打开"生活在长大"的界面 程序首页展示校园服务,论坛等相关信息 用户选择留言板 程序界面跳转 用户查看留言,并可以输入留言内容 提交 ...

  10. 微信小程序开发之scroll-view

    本文主要介绍通过scroll-view实现回至顶部,如下效果 一.页面代码 顶部的工具栏放一个查找按钮,滚动区域实现分页,目的就是为了点击上一页\下一页时,自动回到顶部. scroll-view必须指 ...