一、这个类是获取操作系统相关信息,包括操作系统版本,真实ip,浏览器版本,这个类中的获取mac地址较慢,建议使用第二种,大部分方式是从HttpServletRequest中即可获取。
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.io.InputStreamReader;
public class ClientOS{
/****
* 获取操作系统
* @param userAgent
* @return
*/
public static String getClientOS(String userAgent){
String cos = "unknow os";
Pattern p = Pattern.compile(".*(Windows NT 10).*");
Matcher m = p.matcher(userAgent);
if(m.find())
{
cos = "Win 10";
return cos;
}
p = Pattern.compile(".*(Windows NT 6\\.1).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Win 7";
return cos;
}
p = Pattern.compile(".*(Windows NT 5\\.1|Windows XP).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "WinXP";
return cos;
}
p = Pattern.compile(".*(Windows NT 5\\.2).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Win2003";
return cos;
}
p = Pattern.compile(".*(Win2000|Windows 2000|Windows NT 5\\.0).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Win2000";
return cos;
}
p = Pattern.compile(".*(Mac|apple|MacOS8).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "MAC";
return cos;
}
p = Pattern.compile(".*(WinNT|Windows NT).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "WinNT";
return cos;
}
p = Pattern.compile(".*Linux.*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Linux";
return cos;
}
p = Pattern.compile(".*(68k|68000).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Mac68k";
return cos;
}
p = Pattern.compile(".*(9x 4.90|Win9(5|8)|Windows 9(5|8)|95/NT|Win32|32bit).*");
m = p.matcher(userAgent);
if(m.find())
{
cos = "Win9x";
return cos;
}
return cos;
}
/***
* 获取真实ip
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknow".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
//根据网卡获取本机配置的IP地址
InetAddress inetAddress = null;
try {
inetAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
ipAddress = inetAddress.getHostAddress();
}
}
//对于通过多个代理的情况,第一个IP为客户端真实的IP地址,多个IP按照','分割
if(null != ipAddress && ipAddress.length() > 15){
//"***.***.***.***".length() = 15
if(ipAddress.indexOf(",") > 0){
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
/**
* 获取来访者的浏览器版本
* @param request
* @return
*/
public static String getRequestBrowserInfo(HttpServletRequest request){
String browserVersion = null;
String header = request.getHeader("user-agent");
if(header == null || header.equals("")){
return "";
}
if(header.indexOf("MSIE")>0){
browserVersion = "IE";
}else if(header.indexOf("Firefox")>0){
browserVersion = "Firefox";
}else if(header.indexOf("Chrome")>0){
browserVersion = "Chrome";
}else if(header.indexOf("Safari")>0){
browserVersion = "Safari";
}else if(header.indexOf("Camino")>0){
browserVersion = "Camino";
}else if(header.indexOf("Konqueror")>0){
browserVersion = "Konqueror";
}
return browserVersion;
}
/**
* 获取来访者的主机名称
* @param ip
* @return
*/
public static String getHostName(String ip){
InetAddress inet;
try {
inet = InetAddress.getByName(ip);
return inet.getHostName();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "";
}
/**
* 命令获取mac地址
* @param cmd
* @return
*/
private static String callCmd(String[] cmd) {
String result = "";
String line = "";
try {
Process proc = Runtime.getRuntime().exec(cmd);
InputStreamReader is = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader (is);
while ((line = br.readLine ()) != null) {
result += line;
}
}catch(Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
*
*
* @param cmd
* 第一个命令
*
* @param another
* 第二个命令
*
* @return 第二个命令的执行结果
*
*/
private static String callCmd(String[] cmd,String[] another) {
String result = "";
String line = "";
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
proc.waitFor(); // 已经执行完第一个命令,准备执行第二个命令
proc = rt.exec(another);
InputStreamReader is = new InputStreamReader(proc.getInputStream());
BufferedReader br = new BufferedReader (is);
while ((line = br.readLine ()) != null) {
result += line;
}
}catch(Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
*
*
* @param ip
* 目标ip,一般在局域网内
*
* @param sourceString
* 命令处理的结果字符串
*
* @param macSeparator
* mac分隔符号
*
* @return mac地址,用上面的分隔符号表示
*
*/
private static String filterMacAddress(final String ip, final String sourceString,final String macSeparator) {
String result = "";
String regExp = "((([0-9,A-F,a-f]{1,2}" + macSeparator + "){1,5})[0-9,A-F,a-f]{1,2})";
Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(sourceString);
while(matcher.find()){
result = matcher.group(1);
if(sourceString.indexOf(ip) <= sourceString.lastIndexOf(matcher.group(1))) {
break; // 如果有多个IP,只匹配本IP对应的Mac.
}
}
return result;
}
/**
* @param ip
* 目标ip
* @return Mac Address
*
*/
private static String getMacInWindows(final String ip){
String result = "";
String[] cmd = {"cmd","/c","ping " + ip};
String[] another = {"cmd","/c","arp -a"};
String cmdResult = callCmd(cmd,another);
result = filterMacAddress(ip,cmdResult,"-");
return result;
}
/**
*
* @param ip
* 目标ip
* @return Mac Address
*
*/
private static String getMacInLinux(final String ip){
String result = "";
String[] cmd = {"/bin/sh","-c","ping " + ip + " -c 2 && arp -a" };
String cmdResult = callCmd(cmd);
result = filterMacAddress(ip,cmdResult,":");
return result;
}
/**
* 获取MAC地址
*
* @return 返回MAC地址
*/
public static String getMacAddress(String ip){
String macAddress = "";
macAddress = getMacInWindows(ip).trim();
if(macAddress==null||"".equals(macAddress)){
macAddress = getMacInLinux(ip).trim();
}
return macAddress;
}
}
二、这个类是获取网卡的mac地址,是通过向客户端发送一个UDP询问包,然后解析返回数据。,采用137端口。
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.concurrent.*;
/**
* 主机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地址的方法
* 用法 :new UdpGetClientMacAddr(ip地址)
* @author WINDY
*/
public class UdpGetClientMacAddr {
private String sRemoteAddr;
private int iRemotePort=137;
private byte[] buffer = new byte[1024];
private DatagramSocket ds=null;
final ExecutorService exec = Executors.newFixedThreadPool(1);
DatagramPacket dp=null;
public UdpGetClientMacAddr(String strAddr) throws Exception{
sRemoteAddr = strAddr;
ds = new DatagramSocket();
}
protected final DatagramPacket send(final byte[] bytes) throws IOException {
DatagramPacket dp = new DatagramPacket(bytes,bytes.length,InetAddress.getByName(sRemoteAddr),iRemotePort);
ds.send(dp);
return dp;
}
protected final DatagramPacket receive() throws Exception {
dp = new DatagramPacket(buffer,buffer.length);
ds.receive(dp);
return dp;
}
// 询问包结构:
// Transaction ID 两字节(16位) 0x00 0x00
// Flags 两字节(16位) 0x00 0x10
// Questions 两字节(16位) 0x00 0x01
// AnswerRRs 两字节(16位) 0x00 0x00
// AuthorityRRs 两字节(16位) 0x00 0x00
// AdditionalRRs 两字节(16位) 0x00 0x00
// Name:array [1..34] 0x20 0x43 0x4B 0x41(30个) 0x00 ;
// Type:NBSTAT 两字节 0x00 0x21
// Class:INET 两字节(16位)0x00 0x01
protected 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;
}
// 表1 “UDP-NetBIOS-NS”应答包的结构及主要字段一览表
// 序号 字段名 长度
// 1 Transaction ID 两字节(16位)
// 2 Flags 两字节(16位)
// 3 Questions 两字节(16位)
// 4 AnswerRRs 两字节(16位)
// 5 AuthorityRRs 两字节(16位)
// 6 AdditionalRRs 两字节(16位)
// 7 Name<Workstation/Redirector> 34字节(272位)
// 8 Type:NBSTAT 两字节(16位)
// 9 Class:INET 两字节(16位)
// 10 Time To Live 四字节(32位)
// 11 Length 两字节(16位)
// 12 Number of name 一个字节(8位)
// NetBIOS Name Info 18×Number Of Name字节
// Unit ID 6字节(48位
protected 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() {
try
{
ds.close();
}
catch (Exception ex){
ex.printStackTrace();
}
}
public final String GetRemoteMacAddr() {
String smac = null;
try {
byte[] bqcmd = GetQueryCmd();
send(bqcmd);
//DatagramPacket dp = receive();
Future<DatagramPacket> future = exec.submit(call);
DatagramPacket dp = future.get(1000 * 1, TimeUnit.MILLISECONDS);
smac = GetMacAddr(dp.getData());
close();
} catch (Exception e) {
e.printStackTrace();
}
return smac;
}
Callable<DatagramPacket> call = new Callable<DatagramPacket>() {
public DatagramPacket call() throws Exception {
//开始执行耗时操作
return receive();
}
};
}
我的笔记博客版权
我的笔记博客版权