JAVA之——获取来访者IP、浏览器版本、系统版本、主机名、Mac地址等信息(插曲)

时间:2021-11-23 14:25:32
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46049885

不多说,直接上代码

package com.cdsmartlink.utils.system;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

/**
 * 获取系统的信息
 * @author liuyazhuang
 *
 */
public final class SystemUtils {
	/**
     * 获取访问者IP
     * 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效。
     * 
     * 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-For获得第一个IP(用,分割),
     * 如果还不存在则调用Request .getRemoteAddr()。
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (ip!= null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (ip!= null && !"".equals(ip)  && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个IP值,第一个为真实IP。
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }
    
    /**
     * 获取来访者的浏览器版本
     * @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 request
     * @return
     */
    public static String getRequestSystemInfo(HttpServletRequest request){
	  String systenInfo = null;
	  String header = request.getHeader("user-agent");
	  if(header == null || header.equals("")){
	   return "";
	  }
        //得到用户的操作系统
        if (header.indexOf("NT 6.0") > 0){
            systenInfo = "Windows Vista/Server 2008";
        } else if (header.indexOf("NT 5.2") > 0){
            systenInfo = "Windows Server 2003";
        } else if (header.indexOf("NT 5.1") > 0){
            systenInfo = "Windows XP";
        } else if (header.indexOf("NT 6.0") > 0){
            systenInfo = "Windows Vista";
        } else if (header.indexOf("NT 6.1") > 0){
            systenInfo = "Windows 7";
        } else if (header.indexOf("NT 6.2") > 0){
            systenInfo = "Windows Slate";
        } else if (header.indexOf("NT 6.3") > 0){
            systenInfo = "Windows 9";
        } else if (header.indexOf("NT 5") > 0){
            systenInfo = "Windows 2000";
        } else if (header.indexOf("NT 4") > 0){
            systenInfo = "Windows NT4";
        } else if (header.indexOf("Me") > 0){
            systenInfo = "Windows Me";
        } else if (header.indexOf("98") > 0){
            systenInfo = "Windows 98";
        } else if (header.indexOf("95") > 0){
            systenInfo = "Windows 95";
        } else if (header.indexOf("Mac") > 0){
            systenInfo = "Mac";
        } else if (header.indexOf("Unix") > 0){
            systenInfo = "UNIX";
        } else if (header.indexOf("Linux") > 0){
            systenInfo = "Linux";
        } else if (header.indexOf("SunOS") > 0){
            systenInfo = "SunOS";
        }
        return systenInfo;
	 }
    
    /**
     * 获取来访者的主机名称
     * @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;
    	 }
}

最近,有读者反馈说上述代码取不到Win10系统下正确的Mac地址,根据读者的反馈,我对根据IP获取Mac地址的代码进行了相关的优化,支持Win10+Linux,不多说了,具体看如下代码。同时,感谢大家对鄙人的鼓励和关注,你们的鼓励和关注是我分享博客的最大动力!

package com.lyz.mac;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 根据IP获取对应的Mac地址,支持win10+Linux
 * @author liuyazhuang
 *
 */
public class MacAddress {
	
	/**
	 * 调用命令
	 * @param cmd
	 * @return
	 */
	public 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 第二个命令的执行结果
	 */
	public 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地址,用上面的分隔符号表示
	 */
	public static String filterMacAddress(final String ip, String sourceString, final String macSeparator) {
		String result = "";
		int index = sourceString.indexOf(ip);
		if (index == -1) {
			index = 0;
		}
		sourceString = sourceString.substring(index, sourceString.length() - 1);
		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
	 */
	public 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
	 *
	 */
	public 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;
	}

	// //做个测试
	public static void main(String[] args) {
		System.out.println(MacAddress.getMacAddress("10.2.2.93"));
		System.out.println(MacAddress.getMacAddress("10.2.2.71"));
	}
}

获取同一局域网内的所有IP和对应的Mac,具体代码如下:

package com.lyz.mac;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 获取同一局域网内的所有IP和对应的Mac
 * @author liuyazhuang
 *
 */
public class AllAddress {
	
	/**
	 * 获取统一局域网的所有IP地址
	 * @return 所有IP地址的List集合
	 */
	public static List<String> getIPs() {
		List<String> list = new ArrayList<String>();
		Runtime r = Runtime.getRuntime();
		Process p;
		try {
			p = r.exec("arp -a");
			BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
			String inline;
			while ((inline = br.readLine()) != null) {
				if(!"".equals(inline.trim())){
					if (inline.indexOf("---") > -1) {
						continue;
					}
					if(inline.indexOf("Internet") > -1){
						continue;
					}
					// 有效IP
					String[] str = inline.split(" {4}");
					list.add(str[0]);
//					System.out.println(inline);
				}
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return list;
	}
	
	/**
	 * 获取同一局域网内的IP和Mac
	 * @return 以IP地址为Key, Mac地址为Value的Map
	 */
	public static Map<String, String> getAllIPAndMac(){
		  Map<String,String> map = new HashMap<String,String>();
		  Runtime r = Runtime.getRuntime();
			Process p;
			try {
				p = r.exec("arp -a");
				BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
				String inline;
				while ((inline = br.readLine()) != null) {
					if(!"".equals(inline.trim())){
						if (inline.indexOf("---") > -1) {
							continue;
						}
						if(inline.indexOf("Internet") > -1){
							continue;
						}
						// 有效IP
						String[] arr = inline.split(" {4}");
						String ip = arr[0].trim();
						String mac = "00-00-00-00-00-00";
						for(int i = 1; i < arr.length; i ++){
							String str = arr[i].trim();
							if(stringIsMac(str)){
								mac = str;
								break;
							}
						}
						map.put(ip, mac);
					}
				}
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		  return map;
	}
	
	 /**
	  * 根据正则表达式判断是否为Mac地址
	 * @param val
	 * @return true:是Mac地址,false:不是Mac地址
	 */
	private static boolean stringIsMac(String val) {  
        String trueMacAddress = "^([0-9a-fA-F]{2})(([/\\s:-][0-9a-fA-F]{2}){5})$";  
        // 这是真正的MAC地址;正则表达式;  
        return val.matches(trueMacAddress);
	}  
	
	/**
	 * 根据IP提取主机名
	 * @param ips
	 * @return 以IP地址为Key,主机名为Value的Map
	 */
	public static Map<String, String> getHostnames(List<String> ips){
        Map<String,String> map = new HashMap<String,String>();
        System.out.println("正在提取hostname...");
        for(String ip : ips){
            String command = "ping -a " + ip;
            Runtime r = Runtime.getRuntime();
            Process p;
            try {
                p = r.exec(command);
                BufferedReader br = new BufferedReader(new InputStreamReader(p .getInputStream()));
                String inline;
                while ((inline = br.readLine()) != null) {
                    if(inline.indexOf("[") > -1){
                        int start = inline.indexOf("Ping ");
                        int end = inline.indexOf("[");
                        String hostname = inline.substring(start+"Ping ".length(),end-1);
                        System.out.println(hostname);
                        map.put(ip,hostname);
                    }
                }
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("提取结束!");
        return map;
    }
	
	public static void main(String[] args) {
		System.out.println(getIPs());
		System.out.println(getAllIPAndMac());
	}
}