hac103 发表于 2013-1-15 02:18:53

java取客户mac地址

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;    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 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;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x10;      t_ns = 0x00;      t_ns = 0x01;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x20;      t_ns = 0x43;      t_ns = 0x4B;      for (int i = 15; i < 45; i++) {            t_ns = 0x41;      }      t_ns = 0x00;      t_ns = 0x00;      t_ns = 0x21;      t_ns = 0x00;      t_ns = 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 * 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);            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.txtMACAddr.value = unescape(MACAddr); document.forms.txtIPAddr.value = unescape(IPAddr); document.forms.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) {                        /**                        *寻找标示字符串                         */                  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) {                              /**                            *寻找标示字符串                           */                        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端口。
 
 
页: [1]
查看完整版本: java取客户mac地址