六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 121|回复: 0

java取客户mac地址

[复制链接]

升级  6%

17

主题

17

主题

17

主题

秀才

Rank: 2

积分
59
 楼主| 发表于 2013-1-15 02:18:53 | 显示全部楼层 |阅读模式
NND,很多人都不装插件,没办法只能想另外的办法取mac。网上(http://wangxuliangboy.iteye.com/blog/374298)找了一下代码回来改,只改了部分先存在这里
import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;//import javax.servlet.http.HttpServletRequest;/** * 主机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();    }    protected final DatagramPacket send(final byte[] bytes) throws IOException {        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(sRemoteAddr), iRemotePort);        ds.setSoTimeout(2000);        ds.send(dp);        return dp;    }    protected final DatagramPacket receive() throws Exception {        DatagramPacket 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 {        // 获取计算机名        System.out.println(new String(brevdata, 57, 18));        System.out.println(new String(brevdata, 75, 18));        System.out.println(new String(brevdata, 93, 18));        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() throws Exception {        byte[] bqcmd = GetQueryCmd();        send(bqcmd);        try{        DatagramPacket dp = receive();        String smac = GetMacAddr(dp.getData());            close();            return smac;        }catch(java.net.SocketTimeoutException e){        close();        return "0x000000000000";        }finally{        close();        }    }    public static void main(String[] args) throws Exception {        UdpGetClientMacAddr addr = new UdpGetClientMacAddr("10.182.129.195");        System.out.println(addr.GetRemoteMacAddr());    }       /*// 获取真实IP的方法()    public String getIpAddr(HttpServletRequest request) {           String ip = request.getHeader("x-forwarded-for");           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {               ip = request.getHeader("Proxy-Client-IP");           }           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {               ip = request.getHeader("WL-Proxy-Client-IP");           }           if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {               ip = request.getRemoteAddr();           }           return ip;       }*/}  
总结一下,现在一般有3中方法获取mac地址
1.通过ActiveX的方法
2.通过在客户端运行ipconfig这类dos或者shell命令
3.就是前面那种通过发送udp包,得到应答后分析取mac地址
 
 
1.通过ActiveX的方法,这个的问题就是这能跑在ie这类浏览器上,而且客户如果不允许插件运行,那也获取不了,太依赖客户行为。获取mac代码,我懒得整理了,直接从http://hi.baidu.com/fangqm/blog/item/d3f7c5eae1c1ecdbd539c93f.html这里cp过来,
<HTML><HEAD>     <TITLE>读取客户端MAC</TITLE>     <META http-equiv=Content-Type c>     <SCRIPT language=JScript event="OnCompleted(hResult,pErrorObject, pAsyncContext)" for=mac>         document.forms[0].txtMACAddr.value = unescape(MACAddr); document.forms[0].txtIPAddr.value = unescape(IPAddr); document.forms[0].txtDNSName.value = unescape(sDNSName);     </SCRIPT>     <SCRIPT language=JScript event=OnObjectReady(objObject,objAsyncContext) for=mac>         if (objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true)         {             if (objObject.MACAddress != null && objObject.MACAddress != "undefined")                 MACAddr = objObject.MACAddress;   //获取MAC地址             if (objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined")                 IPAddr = objObject.IPAddress(0); //获取IP地址             if (objObject.DNSHostName != null && objObject.DNSHostName != "undefined")                 sDNSName = objObject.DNSHostName;//获取计算机名         }     </SCRIPT>     <META c name=GENERATOR></HEAD><BODY><OBJECT id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></OBJECT><OBJECT id=mac classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT><SCRIPT language=JScript>     var service = locator.ConnectServer();     var MACAddr ;     var IPAddr ;     var DomainAddr;     var sDNSName;     service.Security_.ImpersonationLevel = 3;     service.InstancesOfAsync(mac, 'Win32_NetworkAdapterConfiguration');</SCRIPT><FORM id=formfoo name=formbar action=readMACAction.do method=post>     <INPUT value="" name=txtMACAddr>     <INPUT value="" name=txtIPAddr>     <INPUT value="" name=txtDNSName></FORM></BODY></HTML>  
2.通过在客户端运行ipconfig这类dos或者shell命令,这个的缺点就是如果在客户机子不允许/不能运行该类命令或者客户修改了该类命令(如ipconfig修改为ipcon)。另外还有可能在运行命令的时候发生阻塞,这个时候你就不知道什么时候能获取mac了。
 
获取方法还是懒得自己再写了,从http://blog.163.com/09zzy@126/blog/static/71197665201001504753750/拷贝过来
 
 
import java.io.BufferedReader;    import java.io.IOException;    import java.io.InputStreamReader;       /**    * 获取MAC地址    * @author sunlightcs    *    */   public class GetMacAddress {             /**           *  获取当前操作系统名称.           *  return 操作系统名称 例如:windows,Linux,Unix等.          */           public static String getOSName() {               return System.getProperty("os.name").toLowerCase();           }                          /**           * 获取Unix网卡的mac地址.          * @return mac地址          */           public static String getUnixMACAddress() {               String mac = null;               BufferedReader bufferedReader = null;               Process process = null;               try {                     /**                   *  Unix下的命令,一般取eth0作为本地主网卡 显示信息中包含有mac地址信息                     */                process = Runtime.getRuntime().exec("ifconfig eth0");                 bufferedReader = new BufferedReader(new InputStreamReader(process                           .getInputStream()));                   String line = null;                   int index = -1;                   while ((line = bufferedReader.readLine()) != null) {                          /**                        *  寻找标示字符串[hwaddr]                         */                    index = line.toLowerCase().indexOf("hwaddr");                         /**                        * 找到了                        */                    if (index != -1) {                              /**                            *   取出mac地址并去除2边空格                              */                        mac = line.substring(index +"hwaddr".length()+ 1).trim();                         break;                       }                   }               } catch (IOException e) {                   e.printStackTrace();               } finally {                   try {                       if (bufferedReader != null) {                           bufferedReader.close();                       }                   } catch (IOException e1) {                      e1.printStackTrace();                  }                   bufferedReader = null;                   process = null;               }                      return mac;           }                                                    /**               * 获取Linux网卡的mac地址.              * @return mac地址              */               public static String getLinuxMACAddress() {                   String mac = null;                   BufferedReader bufferedReader = null;                   Process process = null;                   try {                         /**                       *  linux下的命令,一般取eth0作为本地主网卡 显示信息中包含有mac地址信息                         */                    process = Runtime.getRuntime().exec("ifconfig eth0");                     bufferedReader = new BufferedReader(new InputStreamReader(process                               .getInputStream()));                       String line = null;                       int index = -1;                       while ((line = bufferedReader.readLine()) != null) {                           index = line.toLowerCase().indexOf("硬件地址");                             /**                            * 找到了                            */                        if (index != -1) {                                  /**                                *   取出mac地址并去除2边空格                                  */                            mac = line.substring(index+4).trim();                             break;                           }                       }                   } catch (IOException e) {                       e.printStackTrace();                   } finally {                       try {                           if (bufferedReader != null) {                               bufferedReader.close();                           }                       } catch (IOException e1) {                          e1.printStackTrace();                      }                       bufferedReader = null;                       process = null;                   }                            return mac;               }                          /**              * 获取widnows网卡的mac地址.              * @return mac地址              */               public static String getWindowsMACAddress() {                   String mac = null;                   BufferedReader bufferedReader = null;                   Process process = null;                   try {                         /**                       * windows下的命令,显示信息中包含有mac地址信息                         */                    process = Runtime.getRuntime().exec("ipconfig /all");                     bufferedReader = new BufferedReader(new InputStreamReader(process                               .getInputStream()));                       String line = null;                       int index = -1;                       while ((line = bufferedReader.readLine()) != null) {                              /**                            *  寻找标示字符串[physical address]                             */                        index = line.toLowerCase().indexOf("physical address");                          if (index != -1) {                             index = line.indexOf(":");                             if (index != -1) {                                    /**                                    *   取出mac地址并去除2边空格                                    */                               mac = line.substring(index + 1).trim();                             }                             break;                           }                     }                 } catch (IOException e) {                       e.printStackTrace();                   }finally {                       try {                           if (bufferedReader != null) {                               bufferedReader.close();                             }                       }catch (IOException e1) {                           e1.printStackTrace();                         }                       bufferedReader = null;                       process = null;                   }                              return mac;               }                          /**              * 测试用的main方法.              *               * @param argc             *            运行参数.              */               public static void main(String[] argc) {                   String os = getOSName();                   System.out.println(os);                   if(os.startsWith("windows")){                       String mac = getWindowsMACAddress();                       System.out.println("本地是windows:"+mac);                   }else if(os.startsWith("linux")){                         String mac = getLinuxMACAddress();                       System.out.println("本地是Linux系统,MAC地址是:"+mac);                 }else{                       String mac = getUnixMACAddress();                                           System.out.println("本地是Unix系统 MAC地址是:"+mac);                 }               }         }   3.就是前面那种通过发送udp包,得到应答后分析取mac地址。缺点,首先你要获取准确的客户ip,并且客户机开发了netbios服务和137端口。
 
 
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表