ASP.NET获取客户端IP及Mac地址

2011-12-07 13:12:56 作者: 所属分类:Web前端 阅读:808 评论:8

标签:

最近在做电子政务,给某局以及直属单位做统一的用户登录功能。登录界面有多级选择列表,如:局单位-->局业务处室-->局用户-->用户名,每次登录都得这么选择,繁琐的操作对那些机关领导来说确实是一件不容易的事,为此就希望把用户选择的信息,初始化一次,以后登录就不用再选择那么多了。于是就想到记录客户端的MAC地址来做为机器标识。但要在客户端能快速准确的获取到MAC地址还是一件不太容易的事。主要常见的方式有以下几种:

方法一:Javascript结合系统的ActiveX

优点:无需开发额外的代码,轻量级的实现。不需要服务器端进行处理,有客户端自行获取,传递到服务器端,速度比在服务器端获取好。
缺点:受客服端平台的限制,如安全级别设置较高,则无常正常执行。还有情况就是可靠性不是怎么好,有获取不到的情况。

其实最关键的还是用到两个ActiveX:
<OBJECT id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></OBJECT>
<OBJECT id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></OBJECT>

两个ActiveX都是系统自带,不用去下载或注册。

Code

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2.  
  3. <html>  
  4.     <head><title>WMI Scripting HTML</title>  
  5. <META http-equiv="Content-Type" content="text/html; charset=gb2312">  
  6. <script language="JScript" event="OnCompleted(hResult,pErrorObject, pAsyncContext)" for=foo>  
  7. document.forms[0].txtMACAddr.value=unescape(MACAddr);  
  8. document.forms[0].txtIPAddr.value=unescape(IPAddr);  
  9. document.forms[0].txtDNSName.value=unescape(sDNSName);  
  10.  //document.formbar.submit();  
  11.   </script>  
  12.  
  13. <script language="JScript" event=OnObjectReady(objObject,objAsyncContext) for=foo>  
  14.    if(objObject.IPEnabled != null && objObject.IPEnabled != "undefined" && objObject.IPEnabled == true)  
  15.    {  
  16.     if(objObject.MACAddress != null && objObject.MACAddress != "undefined")  
  17.     MACAddr = objObject.MACAddress;  
  18.     if(objObject.IPEnabled && objObject.IPAddress(0) != null && objObject.IPAddress(0) != "undefined")  
  19.     IPAddr = objObject.IPAddress(0);  
  20.     if(objObject.DNSHostName != null && objObject.DNSHostName != "undefined")  
  21.     sDNSName = objObject.DNSHostName;  
  22.     }  
  23.   </script>  
  24.  
  25.     <META content="MSHTML 6.00.2800.1106" name=GENERATOR>  
  26. </head>  
  27. <body>  
  28. <object id=locator classid=CLSID:76A64158-CB41-11D1-8B02-00600806D9B6 VIEWASTEXT></object>  
  29. <object id=foo classid=CLSID:75718C9A-F029-11d1-A1AC-00C04FB6C223></object>  
  30.    <script language="JScript">  
  31.        var service = locator.ConnectServer();  
  32.        var MACAddr ;  
  33.        var IPAddr ;  
  34.        var DomainAddr;  
  35.        var sDNSName;  
  36.        service.Security_.ImpersonationLevel=3;  
  37.        service.InstancesOfAsync(foo, 'Win32_NetworkAdapterConfiguration');  
  38.    </script>  
  39.  
  40. <form  runat="server" id="formfoo" name="formbar" method="post">  
  41.     <input  name="txtMACAddr"/>  
  42.     <input  name="txtIPAddr"/>  
  43.     <input  name="txtDNSName"/>  
  44.     <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />  
  45. </form>  
  46. </body>  
  47. </html> 

 

方法二:调用Win32API(推荐)

优点:成功率较高,不受客户浏览器的限制。
缺点:只能是Windows系统

Code

  1.     [DllImport("Iphlpapi.dll")]  
  2.     private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);  
  3.     [DllImport("Ws2_32.dll")]  
  4.     private static extern Int32 inet_addr(string ip);  
  5.  
  6. private string GetClientIP()  
  7.     {  
  8.         string result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];  
  9.         if (null == result || result == String.Empty)  
  10.         {  
  11.             result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];  
  12.         }  
  13.  
  14.         if (null == result || result == String.Empty)  
  15.         {  
  16.             result = HttpContext.Current.Request.UserHostAddress;  
  17.         }  
  18.         return result;  
  19.     }  
  20.  
  21. /// <summary>  
  22.     /// 获取Mac地址信息  
  23.     /// </summary>  
  24.     /// <param name="IP"></param>  
  25.     /// <returns></returns>  
  26.     public static string GetCustomerMac(string IP)  
  27.     {  
  28.         Int32 ldest = inet_addr(IP);  
  29.         Int64 macinfo = new Int64();  
  30.         Int32 len = 6;  
  31.         int res = SendARP(ldest, 0, ref macinfo, ref len);  
  32.         string mac_src = macinfo.ToString("X");  
  33.  
  34.         while (mac_src.Length < 12)  
  35.         {  
  36.             mac_src = mac_src.Insert(0, "0");  
  37.         }  
  38.  
  39.         string mac_dest = "";  
  40.  
  41.         for (int i = 0; i < 11; i++)  
  42.         {  
  43.             if (0 == (i % 2))  
  44.             {  
  45.                 if (i == 10)  
  46.                 {  
  47.                     mac_dest = mac_dest.Insert(0, mac_src.Substring(i, 2));  
  48.                 }  
  49.                 else 
  50.                 {  
  51.                     mac_dest = "-" + mac_dest.Insert(0, mac_src.Substring(i, 2));  
  52.                 }  
  53.             }  
  54.         }  
  55.  
  56.         return mac_dest;  
  57.     } 

 

方法三:后台进程调用nbtstat命令

优点:无需额外开发组件,不受客户端平台的限制
缺点:受网络范围的限制,成功率较低,速度慢。

具体实现原理:通过nbtstat -a IP 命令将对方计算机的信息输出管道,然后捕获管道输出的内容,再通过正则表达式将MAC筛选出来。

Code

  1. public static string GetCustomerMac(string IP)  
  2. {  
  3.     string dirResults = "";  
  4.     ProcessStartInfo psi = new ProcessStartInfo();  
  5.     Process proc = new Process();  
  6.     psi.FileName = "nbtstat";  
  7.     psi.RedirectStandardInput = false;  
  8.     psi.RedirectStandardOutput = true;  
  9.     psi.Arguments = "-A " + IP;  
  10.     psi.UseShellExecute = false;  
  11.     proc = Process.Start(psi);  
  12.     dirResults = proc.StandardOutput.ReadToEnd();  
  13.     proc.WaitForExit();  
  14.     dirResults = dirResults.Replace("\r", "").Replace("\n", "").Replace("\t", "");  
  15.     Regex reg = new Regex("([0-9A-Fa-f]{2})(-[0-9A-Fa-f]{2}){5}", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.RightToLeft);  
  16.     Match mc = reg.Match(dirResults);  
  17.     if (mc.Success)  
  18.     {  
  19.         try 
  20.         {  
  21.             return mc.Groups[0].Value.ToString();  
  22.         }  
  23.         catch 
  24.         {  
  25.             return "";  
  26.         }  
  27.     }  
  28.     else 
  29.     {  
  30.         reg = new Regex("Host not found", RegexOptions.IgnoreCase | RegexOptions.Compiled);  
  31.         mc = reg.Match(dirResults);  
  32.         if (mc.Success)  
  33.         {  
  34.             return "Host not found!";  
  35.         }  
  36.         else 
  37.         {  
  38.             return "";  
  39.         }  
  40.     }  

 

上述三种方式,都经过测试,第一种方式,会有获取不到MAC地址的情况;第三种方式,奇慢无比,尤其当服务器有多个网卡时,相当慢。我自己的机器有两个网卡时,程序基本卡死,半天才能响应;改成第二种之后,情况改观了很多,效率都还不错。如果使用ASP.NET获取MAC地址,推荐使用第二种方式。

» 郑重声明:本文由IT伯伯发布,所有内容仅代表个人观点。版权归IT伯伯IT伯伯共有,欢迎转载, 但未经作者同意必须保留此段声明,并给出文章连接,否则保留追究法律责任的权利! 如果本文侵犯了您的权益,请留言。
【上一篇】
【下一篇】

目前有 8 条留言 其中:访客:4 条, 博主:3 条

  1. bawfgfhv CHINA Internet Explorer Windows : 2012年04月07日08:33:11 地板 @回复 回复

    :oops: 试着用了一下,第一种基本上所有浏览器,都默认禁用了,第二种在局域网内可行,一到弄到外网再访问时,取到的MAC 就是一串儿00,第三种,就你说的一样,慢到不行, :arrow:

    • 头像 IT伯伯 CHINA Mozilla Firefox Windows : 2012年04月07日20:12:36 @回复 回复

      是的,三种方法都不好。第二种不仅仅是局域网,还需要在同一个号段中才能使用。不然取的值也全是0

  2. love CHINA Google Chrome Windows : 2011年12月08日17:07:58 板凳 @回复 回复

    这个是实实在在自己用到过,也折腾过的,收藏起来就是价值~~ :evil:

    • 头像 IT伯伯 CHINA Mozilla Firefox Windows : 2012年04月07日20:13:11 @回复 回复

      越来越觉着这个使用的限制太多!

  3. 强壮 CHINA Internet Explorer Windows : 2011年12月07日19:50:03 沙发 @回复 回复

    富婆去夜总会找乐子,挑了几个帅小伙,富婆都不满意;老板娘又挑了几个壮小伙,富婆还是不满意。问富婆到底想要怎么样的?富婆说:要体力好、精力旺、能加班、能熬夜、能创新、随叫随到、吃苦耐劳、充满激情…..老板一下乐了,张口就喊:“干过程序员那几个,出来接客!

    • 过客小小 CHINA Internet Explorer Windows : 2011年12月07日19:53:21 @回复 回复

      :sad:

      • 头像 IT伯伯 CHINA Mozilla Firefox Windows : 2011年12月07日20:12:25 @回复 回复

        悲催的程序员…悲催的命~~ :lol:

给我留言


页面载入中..

展开